mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
814 lines
23 KiB
JavaScript
Executable File
814 lines
23 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
/*!
|
|
* @license
|
|
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
import { Command } from 'commander';
|
|
import fetch from 'node-fetch';
|
|
import * as fs from 'fs';
|
|
import { logger } from './logger';
|
|
import { AlfrescoApi, AlfrescoApiConfig } from '@alfresco/js-api';
|
|
import { argv, exit } from 'node:process';
|
|
|
|
const program = new Command();
|
|
const ACTIVITI_CLOUD_APPS = require('./resources').ACTIVITI_CLOUD_APPS;
|
|
|
|
let alfrescoJsApiModeler: AlfrescoApi;
|
|
let alfrescoJsApiDevops: AlfrescoApi;
|
|
let args: ConfigArgs;
|
|
let isValid = true;
|
|
|
|
export interface ConfigArgs {
|
|
modelerUsername: string;
|
|
modelerPassword: string;
|
|
devopsUsername: string;
|
|
devopsPassword: string;
|
|
oauth: string;
|
|
tokenEndpoint: string;
|
|
clientId: string;
|
|
secret: string;
|
|
scope: string;
|
|
host: string;
|
|
tag: string;
|
|
envs: string[];
|
|
}
|
|
|
|
export const AAE_MICROSERVICES = ['deployment-service', 'modeling-service', 'dmn-service'];
|
|
|
|
/**
|
|
* Perform a health check
|
|
*
|
|
* @param nameService service name
|
|
*/
|
|
async function healthCheck(nameService: string) {
|
|
const url = `${args.host}/${nameService}/actuator/health`;
|
|
|
|
const pathParams = {};
|
|
const queryParams = {};
|
|
const headerParams = {};
|
|
const formParams = {};
|
|
const bodyParam = {};
|
|
const contentTypes = ['application/json'];
|
|
const accepts = ['application/json'];
|
|
|
|
try {
|
|
const health = await alfrescoJsApiModeler.oauth2Auth.callCustomApi(
|
|
url,
|
|
'GET',
|
|
pathParams,
|
|
queryParams,
|
|
headerParams,
|
|
formParams,
|
|
bodyParam,
|
|
contentTypes,
|
|
accepts
|
|
);
|
|
if (health.status !== 'UP') {
|
|
logger.error(`${nameService} is DOWN `);
|
|
isValid = false;
|
|
} else {
|
|
const reset = '\x1b[0m';
|
|
const green = '\x1b[32m';
|
|
logger.info(`${green}${nameService} is UP!${reset}`);
|
|
}
|
|
} catch (error) {
|
|
logger.error(`${nameService} is not reachable error: `, error);
|
|
isValid = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get deployed application
|
|
*
|
|
*/
|
|
async function getApplications(): Promise<{ list: { entries: any[] } }> {
|
|
const url = `${args.host}/deployment-service/v1/applications`;
|
|
|
|
const pathParams = {};
|
|
const queryParams = {};
|
|
const headerParams = {};
|
|
const formParams = {};
|
|
const bodyParam = {};
|
|
const contentTypes = ['application/json'];
|
|
const accepts = ['application/json'];
|
|
|
|
try {
|
|
await alfrescoJsApiDevops.login(args.devopsUsername, args.devopsPassword);
|
|
|
|
const result = alfrescoJsApiDevops.oauth2Auth.callCustomApi(
|
|
url,
|
|
'GET',
|
|
pathParams,
|
|
queryParams,
|
|
headerParams,
|
|
formParams,
|
|
bodyParam,
|
|
contentTypes,
|
|
accepts
|
|
);
|
|
result.on('error', (error) => {
|
|
logger.error(`Get application by status ${error} `);
|
|
});
|
|
return result;
|
|
} catch (error) {
|
|
logger.error(`Get application by status ${error.status} `);
|
|
isValid = false;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get descriptors
|
|
*
|
|
* @returns deployment service descriptors
|
|
*/
|
|
function getDescriptors() {
|
|
const url = `${args.host}/deployment-service/v1/descriptors`;
|
|
|
|
const pathParams = {};
|
|
const queryParams = {};
|
|
const headerParams = {};
|
|
const formParams = {};
|
|
const bodyParam = {};
|
|
const contentTypes = ['application/json'];
|
|
const accepts = ['application/json'];
|
|
|
|
try {
|
|
return alfrescoJsApiDevops.oauth2Auth.callCustomApi(
|
|
url,
|
|
'GET',
|
|
pathParams,
|
|
queryParams,
|
|
headerParams,
|
|
formParams,
|
|
bodyParam,
|
|
contentTypes,
|
|
accepts
|
|
);
|
|
} catch (error) {
|
|
logger.error(`Get Descriptors ${error.status} `);
|
|
isValid = false;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get projects
|
|
*
|
|
* @returns deployment service projects
|
|
*/
|
|
function getProjects() {
|
|
const url = `${args.host}/modeling-service/v1/projects`;
|
|
|
|
const pathParams = {};
|
|
const queryParams = { maxItems: 1000 };
|
|
const headerParams = {};
|
|
const formParams = {};
|
|
const bodyParam = {};
|
|
const contentTypes = ['application/json'];
|
|
const accepts = ['application/json'];
|
|
|
|
try {
|
|
return alfrescoJsApiModeler.oauth2Auth.callCustomApi(
|
|
url,
|
|
'GET',
|
|
pathParams,
|
|
queryParams,
|
|
headerParams,
|
|
formParams,
|
|
bodyParam,
|
|
contentTypes,
|
|
accepts
|
|
);
|
|
} catch (error) {
|
|
logger.error('Get Projects' + error.status);
|
|
isValid = false;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get project release
|
|
*
|
|
* @param projectId project id
|
|
* @returns project release
|
|
*/
|
|
function getProjectRelease(projectId: string) {
|
|
const url = `${args.host}/modeling-service/v1/projects/${projectId}/releases`;
|
|
|
|
const pathParams = {};
|
|
const queryParams = {};
|
|
const headerParams = {};
|
|
const formParams = {};
|
|
const bodyParam = {};
|
|
const contentTypes = ['application/json'];
|
|
const accepts = ['application/json'];
|
|
|
|
try {
|
|
return alfrescoJsApiModeler.oauth2Auth.callCustomApi(
|
|
url,
|
|
'GET',
|
|
pathParams,
|
|
queryParams,
|
|
headerParams,
|
|
formParams,
|
|
bodyParam,
|
|
contentTypes,
|
|
accepts
|
|
);
|
|
} catch (error) {
|
|
logger.error('Get Projects Release' + error.status);
|
|
isValid = false;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Release project
|
|
*
|
|
* @param projectId project id
|
|
*/
|
|
async function releaseProject(projectId: string) {
|
|
const url = `${args.host}/modeling-service/v1/projects/${projectId}/releases`;
|
|
|
|
const pathParams = {};
|
|
const queryParams = {};
|
|
const headerParams = {};
|
|
const formParams = {};
|
|
const bodyParam = {};
|
|
const contentTypes = ['application/json'];
|
|
const accepts = ['application/json'];
|
|
|
|
try {
|
|
return alfrescoJsApiModeler.oauth2Auth.callCustomApi(
|
|
url,
|
|
'POST',
|
|
pathParams,
|
|
queryParams,
|
|
headerParams,
|
|
formParams,
|
|
bodyParam,
|
|
contentTypes,
|
|
accepts
|
|
);
|
|
} catch (error) {
|
|
await deleteProject(projectId);
|
|
logger.error('Post Projects Release' + error.status);
|
|
isValid = false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete project
|
|
*
|
|
* @param projectId project id
|
|
* @returns response payload
|
|
*/
|
|
function deleteProject(projectId: string) {
|
|
const url = `${args.host}/modeling-service/v1/projects/${projectId}`;
|
|
|
|
const pathParams = {};
|
|
const queryParams = {};
|
|
const headerParams = {};
|
|
const formParams = {};
|
|
const bodyParam = {};
|
|
const contentTypes = ['application/json'];
|
|
const accepts = ['application/json'];
|
|
|
|
try {
|
|
return alfrescoJsApiModeler.oauth2Auth.callCustomApi(
|
|
url,
|
|
'DELETE',
|
|
pathParams,
|
|
queryParams,
|
|
headerParams,
|
|
formParams,
|
|
bodyParam,
|
|
contentTypes,
|
|
accepts
|
|
);
|
|
} catch (error) {
|
|
logger.error('Delete project error' + error.status);
|
|
isValid = false;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Import and release project
|
|
*
|
|
* @param absoluteFilePath path to project file
|
|
*/
|
|
async function importAndReleaseProject(absoluteFilePath: string) {
|
|
const fileContent = fs.createReadStream(absoluteFilePath);
|
|
|
|
try {
|
|
const project = await alfrescoJsApiModeler.oauth2Auth.callCustomApi(
|
|
`${args.host}/modeling-service/v1/projects/import`,
|
|
'POST',
|
|
{},
|
|
{},
|
|
{},
|
|
{ file: fileContent },
|
|
{},
|
|
['multipart/form-data'],
|
|
['application/json']
|
|
);
|
|
logger.info(`Project imported`);
|
|
logger.info(`Create release`);
|
|
|
|
return await alfrescoJsApiModeler.oauth2Auth.callCustomApi(
|
|
`${args.host}/modeling-service/v1/projects/${project.entry.id}/releases`,
|
|
'POST',
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
{},
|
|
['application/json'],
|
|
['application/json']
|
|
);
|
|
} catch (error) {
|
|
logger.error(`Not able to import the project/create the release ${absoluteFilePath} with status: ${error}`);
|
|
isValid = false;
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Deletes descriptor
|
|
*
|
|
* @param name descriptor name
|
|
* @returns response payload
|
|
*/
|
|
function deleteDescriptor(name: string) {
|
|
const url = `${args.host}/deployment-service/v1/descriptors/${name}`;
|
|
|
|
const pathParams = {};
|
|
const queryParams = {};
|
|
const headerParams = {};
|
|
const formParams = {};
|
|
const bodyParam = {};
|
|
const contentTypes = ['application/json'];
|
|
const accepts = ['application/json'];
|
|
|
|
try {
|
|
return alfrescoJsApiDevops.oauth2Auth.callCustomApi(
|
|
url,
|
|
'DELETE',
|
|
pathParams,
|
|
queryParams,
|
|
headerParams,
|
|
formParams,
|
|
bodyParam,
|
|
contentTypes,
|
|
accepts
|
|
);
|
|
} catch (error) {
|
|
logger.error('Delete descriptor' + error.status);
|
|
isValid = false;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Deploys a model
|
|
*
|
|
* @param model model object
|
|
* @returns response payload
|
|
*/
|
|
function deploy(model: any) {
|
|
const url = `${args.host}/deployment-service/v1/applications`;
|
|
|
|
const pathParams = {};
|
|
const queryParams = {};
|
|
const headerParams = {};
|
|
const formParams = {};
|
|
const bodyParam = model;
|
|
const contentTypes = ['application/json'];
|
|
const accepts = ['application/json'];
|
|
|
|
try {
|
|
return alfrescoJsApiDevops.oauth2Auth.callCustomApi(
|
|
url,
|
|
'POST',
|
|
pathParams,
|
|
queryParams,
|
|
headerParams,
|
|
formParams,
|
|
bodyParam,
|
|
contentTypes,
|
|
accepts
|
|
);
|
|
} catch (error) {
|
|
logger.error('Deploy post' + error.status);
|
|
isValid = false;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Initialise default endpoint token
|
|
*
|
|
* @param options token options
|
|
* @returns options
|
|
*/
|
|
function initializeDefaultToken(options: ConfigArgs): any {
|
|
options.tokenEndpoint = options.tokenEndpoint.replace('${clientId}', options.clientId);
|
|
return options;
|
|
}
|
|
|
|
/**
|
|
* Get a new Alfresco Api instance
|
|
*
|
|
* @param configArgs command params
|
|
* @returns a new instance of Alfresco Api client
|
|
*/
|
|
function getAlfrescoJsApiInstance(configArgs: ConfigArgs): AlfrescoApi {
|
|
let ssoHost = configArgs.oauth;
|
|
ssoHost = ssoHost ?? configArgs.host;
|
|
|
|
const config: AlfrescoApiConfig = {
|
|
provider: 'BPM',
|
|
hostBpm: `${configArgs.host}`,
|
|
authType: 'OAUTH',
|
|
contextRoot: 'alfresco',
|
|
oauth2: {
|
|
host: `${ssoHost}`,
|
|
tokenUrl: `${ssoHost}/${configArgs.tokenEndpoint}`,
|
|
clientId: `${configArgs.clientId}`,
|
|
scope: `${configArgs.scope}`,
|
|
secret: `${configArgs.secret}`,
|
|
implicitFlow: false,
|
|
silentLogin: false,
|
|
redirectUri: '/'
|
|
}
|
|
};
|
|
return new AlfrescoApi(config);
|
|
}
|
|
|
|
/**
|
|
* Deploy missing applications
|
|
*
|
|
* @param tag tag
|
|
* @param envs environments
|
|
*/
|
|
async function deployMissingApps(tag?: string, envs?: string[]) {
|
|
const deployedApps = await getApplications();
|
|
const failingApps = findFailingApps(deployedApps.list.entries);
|
|
const missingApps = findMissingApps(deployedApps.list.entries);
|
|
|
|
if (failingApps.length > 0) {
|
|
failingApps.forEach((app) => {
|
|
const reset = '\x1b[0m';
|
|
const bright = '\x1b[1m';
|
|
const red = '\x1b[31m';
|
|
logger.error(`${red}${bright}ERROR: App ${app.entry.name} down or inaccessible ${reset}${red} with status ${app.entry.status}${reset}`);
|
|
});
|
|
exit(1);
|
|
} else if (missingApps.length > 0) {
|
|
logger.warn(`Missing apps: ${JSON.stringify(missingApps)}`);
|
|
await checkIfAppIsReleased(missingApps, tag, envs);
|
|
} else {
|
|
const reset = '\x1b[0m';
|
|
const green = '\x1b[32m';
|
|
logger.info(`${green}All the apps are correctly deployed${reset}`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if application is released
|
|
*
|
|
* @param missingApps applications
|
|
* @param tag tag
|
|
* @param envs environments
|
|
*/
|
|
async function checkIfAppIsReleased(missingApps: any[], tag?: string, envs?: string[]) {
|
|
const projectList = await getProjects();
|
|
let TIME = 5000;
|
|
let noError = true;
|
|
|
|
for (let i = 0; i < missingApps.length; i++) {
|
|
noError = true;
|
|
const currentAbsentApp = missingApps[i];
|
|
const project = projectList.list.entries.find((currentApp: any) => currentAbsentApp.name === currentApp.entry.name);
|
|
let projectRelease: any;
|
|
|
|
if (project === undefined) {
|
|
logger.warn('Missing project: Create the project for ' + currentAbsentApp.name);
|
|
|
|
try {
|
|
projectRelease = await importProjectAndRelease(currentAbsentApp, tag);
|
|
} catch (error) {
|
|
logger.info(`error status ${error.status}`);
|
|
|
|
if (error.status !== 409) {
|
|
logger.info(`Not possible to upload the project ${currentAbsentApp.name} status : ${JSON.stringify(error)}`);
|
|
exit(1);
|
|
} else {
|
|
logger.error(`Not possible to upload the project because inconsistency CS - Modelling try to delete manually the node`);
|
|
exit(1);
|
|
}
|
|
}
|
|
} else {
|
|
TIME += 5000;
|
|
|
|
logger.info('Project ' + project.entry.name + ' found');
|
|
|
|
const projectReleaseList = await getProjectRelease(project.entry.id);
|
|
|
|
if (projectReleaseList.list.entries.length === 0) {
|
|
logger.warn('Project needs release');
|
|
projectRelease = await releaseProject(project);
|
|
logger.warn(`Project released: ${projectRelease.id}`);
|
|
} else {
|
|
logger.info('Project already has release');
|
|
|
|
// getting the latest project release
|
|
let currentReleaseVersion = -1;
|
|
projectReleaseList.list.entries.forEach((currentRelease: any) => {
|
|
if (currentRelease.entry.version > currentReleaseVersion) {
|
|
currentReleaseVersion = currentRelease.entry.version;
|
|
projectRelease = currentRelease;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
if (noError) {
|
|
await checkDescriptorExist(currentAbsentApp.name);
|
|
await sleep(TIME);
|
|
|
|
if (envs && envs.length > 0) {
|
|
for (const envId of envs) {
|
|
await deployWithPayload(currentAbsentApp, projectRelease, envId);
|
|
}
|
|
} else {
|
|
await deployWithPayload(currentAbsentApp, projectRelease);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Deploy with a payload
|
|
*
|
|
* @param currentAbsentApp current application
|
|
* @param projectRelease project release
|
|
* @param envId environment id
|
|
*/
|
|
async function deployWithPayload(currentAbsentApp: any, projectRelease: any, envId?: string): Promise<void> {
|
|
const deployPayload = {
|
|
name: currentAbsentApp.name,
|
|
releaseId: projectRelease.entry.id,
|
|
security: currentAbsentApp.security,
|
|
infrastructure: currentAbsentApp.infrastructure,
|
|
variables: currentAbsentApp.variables,
|
|
enableLocalDevelopment: currentAbsentApp.enableLocalDevelopment,
|
|
environmentId: envId
|
|
};
|
|
|
|
logger.info(`Deploying ${currentAbsentApp.name} ${envId ? 'on env: ' + envId : ''}`);
|
|
await deploy(deployPayload);
|
|
logger.info(`Deployed ${currentAbsentApp.name} ${envId ? 'on env: ' + envId : ''}`);
|
|
}
|
|
|
|
/**
|
|
* Check if descriptor exists
|
|
*
|
|
* @param name descriptor name
|
|
*/
|
|
async function checkDescriptorExist(name: string): Promise<boolean> {
|
|
logger.info(`Check descriptor ${name} exist in the list `);
|
|
const descriptorList = await getDescriptors();
|
|
|
|
if (descriptorList?.list && descriptorList.entries) {
|
|
for (const descriptor of descriptorList.list.entries) {
|
|
if (descriptor.entry.name === name) {
|
|
if (descriptor.entry.deployed === false) {
|
|
await deleteDescriptor(descriptor.entry.name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Import and release project
|
|
*
|
|
* @param app application
|
|
* @param tag tag
|
|
*/
|
|
async function importProjectAndRelease(app: any, tag?: string) {
|
|
const appLocationReplaced = app.file_location(tag);
|
|
|
|
logger.warn('App fileLocation ' + appLocationReplaced);
|
|
await getFileFromRemote(appLocationReplaced, app.name);
|
|
|
|
logger.warn('Project imported ' + app.name);
|
|
const projectRelease = await importAndReleaseProject(`${app.name}.zip`);
|
|
|
|
await deleteLocalFile(`${app.name}`);
|
|
return projectRelease;
|
|
}
|
|
|
|
/**
|
|
* Find missing applications
|
|
*
|
|
* @param deployedApps applications
|
|
* @returns list of missing apps
|
|
*/
|
|
function findMissingApps(deployedApps: any[]): any[] {
|
|
const result = [];
|
|
|
|
Object.keys(ACTIVITI_CLOUD_APPS).forEach((key) => {
|
|
const isPresent = deployedApps.find((currentApp: any) => ACTIVITI_CLOUD_APPS[key].name === currentApp.entry.name);
|
|
|
|
if (!isPresent) {
|
|
result.push(ACTIVITI_CLOUD_APPS[key]);
|
|
}
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Find failing applications
|
|
*
|
|
* @param deployedApps applications
|
|
* @returns list of failing apps
|
|
*/
|
|
function findFailingApps(deployedApps: any[]): any[] {
|
|
const result = [];
|
|
|
|
Object.keys(ACTIVITI_CLOUD_APPS).forEach((key) => {
|
|
const failingApp = deployedApps.filter(
|
|
(currentApp: any) => ACTIVITI_CLOUD_APPS[key].name === currentApp.entry.name && 'Deployed' !== currentApp.entry.status
|
|
);
|
|
|
|
if (failingApp?.length > 0) {
|
|
result.push(...failingApp);
|
|
}
|
|
});
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Get file from the remote
|
|
*
|
|
* @param url url to file
|
|
* @param name name
|
|
*/
|
|
async function getFileFromRemote(url: string, name: string): Promise<void> {
|
|
return fetch(url)
|
|
.then((response) => {
|
|
if (!response.ok) {
|
|
throw new Error(`HTTP error! Status: ${response.status}`);
|
|
}
|
|
return response;
|
|
})
|
|
.then(
|
|
(response) =>
|
|
new Promise<void>((resolve, reject) => {
|
|
const outputFile = fs.createWriteStream(`${name}.zip`);
|
|
response.body.pipe(outputFile);
|
|
outputFile.on('finish', () => {
|
|
logger.info(`The file is finished downloading.`);
|
|
resolve();
|
|
});
|
|
outputFile.on('error', (error) => {
|
|
logger.error(`Not possible to download the project form remote`);
|
|
reject(error);
|
|
});
|
|
})
|
|
)
|
|
.catch((error) => {
|
|
logger.error(`Failed to fetch file from remote: ${error.message}`);
|
|
throw error;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Deletes local file
|
|
*
|
|
* @param name file name
|
|
*/
|
|
async function deleteLocalFile(name: string) {
|
|
logger.info(`Deleting local file ${name}.zip`);
|
|
fs.unlinkSync(`${name}.zip`);
|
|
}
|
|
|
|
/**
|
|
* Perform a timeout
|
|
*
|
|
* @param time delay in milliseconds
|
|
*/
|
|
async function sleep(time: number) {
|
|
logger.info(`Waiting for ${time} sec...`);
|
|
await new Promise((done) => setTimeout(done, time));
|
|
logger.info(`Done...`);
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* Init AAE environment command
|
|
*/
|
|
export default async function main() {
|
|
program
|
|
.version('0.1.0')
|
|
.description(
|
|
'The following command is in charge of Initializing the activiti cloud env with the default apps' +
|
|
'adf-cli init-aae-env --host "gateway_env" --modelerUsername "modelerusername" --modelerPassword "modelerpassword" --devopsUsername "devevopsusername" --devopsPassword "devopspassword"'
|
|
)
|
|
.option('-h, --host [type]', 'Host gateway')
|
|
.option('--oauth [type]', 'SSO host')
|
|
.option('--clientId [type]', 'sso client')
|
|
.option('--secret [type]', 'sso secret', '')
|
|
.option('--scope [type]', 'sso scope', 'openid')
|
|
.option('--tokenEndpoint [type]', 'discovery token Endpoint', 'auth/realms/${clientId}/protocol/openid-connect/token')
|
|
.option('--modelerUsername [type]', 'username of a user with role ACTIVIT_MODELER')
|
|
.option('--modelerPassword [type]', 'modeler password')
|
|
.option('--devopsUsername [type]', 'username of a user with role ACTIVIT_DEVOPS')
|
|
.option('--devopsPassword [type]', 'devops password')
|
|
.option('--tag [type]', 'tag name of the codebase')
|
|
.option('--envs [type...]', 'environment ids of the envs where to deploy the app')
|
|
.parse(argv);
|
|
|
|
if (argv.includes('-h') || argv.includes('--help')) {
|
|
program.outputHelp();
|
|
return;
|
|
}
|
|
|
|
const options = initializeDefaultToken(program.opts() as ConfigArgs);
|
|
|
|
args = {
|
|
host: options.host,
|
|
clientId: options.clientId,
|
|
devopsUsername: options.devopsUsername,
|
|
devopsPassword: options.devopsPassword,
|
|
modelerUsername: options.modelerUsername,
|
|
modelerPassword: options.modelerPassword,
|
|
oauth: options.oauth,
|
|
tokenEndpoint: options.tokenEndpoint,
|
|
scope: options.scope,
|
|
secret: options.secret,
|
|
tag: options.tag,
|
|
envs: options.envs
|
|
};
|
|
|
|
alfrescoJsApiModeler = getAlfrescoJsApiInstance(args);
|
|
|
|
AAE_MICROSERVICES.map(async (serviceName) => {
|
|
await healthCheck(serviceName);
|
|
});
|
|
|
|
await alfrescoJsApiModeler.login(args.modelerUsername, args.modelerPassword).then(
|
|
() => {
|
|
const reset = '\x1b[0m';
|
|
const green = '\x1b[32m';
|
|
logger.info(`${green}login SSO ok${reset}`);
|
|
},
|
|
(error) => {
|
|
logger.error(`login SSO error ${JSON.stringify(error)} ${args.modelerUsername}`);
|
|
exit(1);
|
|
}
|
|
);
|
|
|
|
if (isValid) {
|
|
const reset = '\x1b[0m';
|
|
const green = '\x1b[32m';
|
|
logger.info(`${green}The environment is up and running ${reset}`);
|
|
alfrescoJsApiDevops = getAlfrescoJsApiInstance(args);
|
|
await alfrescoJsApiDevops.login(args.devopsUsername, args.devopsPassword).then(
|
|
() => {
|
|
logger.info('login SSO ok devopsUsername');
|
|
},
|
|
(error) => {
|
|
logger.error(`login SSO error ${JSON.stringify(error)} ${args.devopsUsername}`);
|
|
exit(1);
|
|
}
|
|
);
|
|
|
|
await deployMissingApps(args.tag, args.envs);
|
|
} else {
|
|
logger.error('The environment is not up');
|
|
exit(1);
|
|
}
|
|
}
|