import { getServiceAccountToken } from '@axinom/mosaic-id-link-be'; import { isNullOrWhitespace } from '@axinom/mosaic-service-common'; import axios, { AxiosError, AxiosInstance } from 'axios'; import { green, red, yellow } from 'chalk'; import { exitCode } from '../../../../common'; import { GetServiceUndeployOptions } from './service-undeploy-options'; const getAxiosInstance = ( hostingServiceBaseUrl: string, serviceAccountToken: string, ): AxiosInstance => { return axios.create({ baseURL: new URL(hostingServiceBaseUrl).toString(), headers: { Authorization: `Bearer ${serviceAccountToken}`, 'content-type': 'application/json', }, }); }; export const undeployService = async ( args: Required, ): Promise => { const serviceAccountToken = await getServiceAccountToken( args.idServiceAuthBaseURL, args.mosaicHostingClientId, args.mosaicHostingClientSecret, ); const axiosInstance: AxiosInstance = getAxiosInstance( args.hostingServiceBaseURL, serviceAccountToken.accessToken, ); let serviceDeploymentId: string | undefined; if (!isNullOrWhitespace(args.name)) { serviceDeploymentId = await getServiceDeploymentIdByName( args.name, axiosInstance, ); } else { serviceDeploymentId = args.serviceDeploymentId; } if (isNullOrWhitespace(serviceDeploymentId)) { console.log( red(`No Service Deployment was found for name [${args.name}].`), ); return; } const serviceUneployment = JSON.stringify({ query: `mutation InitiateServiceUndeployment($serviceDeploymentId: UUID!) { initiateServiceUndeployment(input: {serviceDeploymentId: $serviceDeploymentId}) { status serviceDeploymentId } }`, variables: { serviceDeploymentId, }, }); try { const response = await axiosInstance.post('graphql', serviceUneployment); if (response.data.errors !== undefined && response.data.errors.length > 0) { console.log( red( `Error while initiating undeployment for Service Deployment ID [${serviceDeploymentId}].`, ), ); console.log(response.data.errors); console.log(); } else { console.log( green( `Undeployment for Service Deployment ID [${serviceDeploymentId}] initiated successfully.`, ), ); console.log( yellow(JSON.stringify(response.data.data?.initiateServiceUndeployment)), ); console.log(); } } catch (error) { console.log( red( `Error while initiating undeployment for Service Deployment ID [${serviceDeploymentId}].`, ), ); console.log(red(JSON.stringify((error as AxiosError).message))); process.exit(exitCode); } }; /** * Validate arguments for Service Undeployment * * @param args * @returns */ export const validateUndeploymentArgs = ( args: GetServiceUndeployOptions, ): [Required, string[]] => { const errorMessages: string[] = []; const idServiceAuthBaseURL = args.idServiceAuthBaseURL ?? process.env.ID_SERVICE_AUTH_BASE_URL ?? ''; const hostingServiceBaseURL = args.hostingServiceBaseURL ?? process.env.HOSTING_SERVICE_BASE_URL ?? ''; const mosaicHostingClientId = args.mosaicHostingClientId ?? process.env.MOSAIC_HOSTING_CLIENT_ID ?? ''; const mosaicHostingClientSecret = args.mosaicHostingClientSecret ?? process.env.MOSAIC_HOSTING_CLIENT_SECRET ?? ''; const name = args.name ?? ''; const serviceDeploymentId = args.serviceDeploymentId ?? ''; if (isNullOrWhitespace(idServiceAuthBaseURL)) { errorMessages.push('[idServiceAuthBaseURL] is required.'); } if (isNullOrWhitespace(mosaicHostingClientId)) { errorMessages.push('[clientId] is required.'); } if (isNullOrWhitespace(mosaicHostingClientSecret)) { errorMessages.push('[clientSecret] is required.'); } if (isNullOrWhitespace(hostingServiceBaseURL)) { errorMessages.push('[hostingServiceBaseURL] is required.'); } if (isNullOrWhitespace(name) && isNullOrWhitespace(serviceDeploymentId)) { errorMessages.push( 'Either the [name] or [serviceDeploymentId] must be provided to initiate the service undeployment.', ); } if (!isNullOrWhitespace(name) && !isNullOrWhitespace(serviceDeploymentId)) { errorMessages.push( 'Only one of [name] or [serviceDeploymentId] arguments must be provided. Both cannot be present.', ); } return [ { name, serviceDeploymentId, idServiceAuthBaseURL, mosaicHostingClientId, mosaicHostingClientSecret, hostingServiceBaseURL, }, errorMessages, ]; }; const getServiceDeploymentIdByName = async ( name: string, axiosInstance: AxiosInstance, ): Promise => { const deploymentInfo = JSON.stringify({ query: `query GetServiceDeploymentIdByName($name: String!) { serviceDeployments(condition: {name: $name}) { nodes { id } } }`, variables: { name, }, }); try { const response = await axiosInstance.post('graphql', deploymentInfo); if (response.data.errors !== undefined && response.data.errors.length > 0) { console.log(red(`Error while retrieving deployment id for [${name}].`)); console.log(response.data.errors); console.log(); } else { return response.data.data?.serviceDeployments?.nodes[0]?.id; } } catch (error) { console.log(red(`Error while retrieving deployment id for [${name}].`)); console.log(JSON.stringify((error as AxiosError).message)); console.log(); } };