UNPKG

@apistudio/apim-cli

Version:

CLI for API Management Products

188 lines (176 loc) 6.24 kB
/** * Copyright IBM Corp. 2024, 2025 */ import axios from 'axios'; import FormData from 'form-data'; import { GatewaysJson, IpcError, Logger } from '@apic/studio-shared'; import { AppConstants } from '../constants/app-constants.js'; export const sendToGateway = async ( gatewayURL: string, gatewayUser: string, gatewaySecret: string, is_mcsp_enabled: boolean, zipBuffer: Buffer, gatewaysJsonContent: GatewaysJson ) => { const formData = new FormData(); formData.append('file', zipBuffer, 'gatewayInstance.zip'); formData.append('overwrite', gatewaysJsonContent.overwrite); let authorizationHeader; if (is_mcsp_enabled) { authorizationHeader = `Bearer ${gatewaySecret}`; } else { const credentials = `${gatewayUser}:${gatewaySecret}`; const encodedCredentials = Buffer.from(credentials).toString('base64'); authorizationHeader = `Basic ${encodedCredentials}`; } return axios .post(gatewayURL + AppConstants.DEPLOY_GATEWAY_URL, formData, { headers: { ...formData.getHeaders(), Authorization: authorizationHeader, }, }) .then((response) => { Logger.debug('Gateway deployment response received', { data: JSON.stringify(response.data), }); const processedResponse = ParseAndFindResponse(response); if (processedResponse && processedResponse.length) { return { success: false, statusCode: response.status, message: 'Api deployment Failed', data: response.data, errors: processedResponse, }; } return { success: true, statusCode: response.status, message: 'Api deployment Successful', data: response.data, errors: [], }; }) .catch((error) => { let errorMessage = error.response?.data?.errorDetails ?? `Response sending to ${gatewayURL}: ${error.message}`; let statusCode = error.response ? error.response.status : 404; let errors = [errorMessage]; // Add error logging Logger.error( 'Gateway deployment failed', error instanceof Error ? error : new Error(String(error)), { gatewayURL, context: 'Gateway Deployment' } ); if (statusCode === 401) { errorMessage = 'Unauthorized: Invalid credentials'; statusCode = 401; errors = ['Unauthorized access: Please check your authentication details.']; } return { success: false, statusCode, message: errorMessage, data: null, errors, }; }); }; export async function validationManager(url: string, authorizationHeader: string) { return axios .get(url, { timeout: 20000, headers: { Authorization: authorizationHeader, }, }) .then((res) => { Logger.debug('Gateway validation response', { data: res.data }); if (res.status === 200) { return { data: 'OK', status: 200 }; } else { Logger.warn(`Unexpected status code: ${res.status}`, { context: 'Validation', }); throw new IpcError(res.data, res.status); } }) .catch((err) => { if (err.response) { const status = err.response.status; const errorData = err.response.data; if (status === 401) { Logger.error('The user name or password did not match.', err, { context: 'Authorization', }); throw new IpcError('The user name or password did not match.', 401, errorData); } else if (status === 502) { Logger.error('Bad Gateway.', err, { context: 'Validation' }); throw new IpcError('Bad Gateway', 502); } else if (status === 404) { Logger.error('Gateway not found.', err, { context: 'Validation' }); throw new IpcError('Gateway not found', 404); } else { Logger.error(`Validation failed with status: ${status}`, err, { context: 'Validation', errorData, }); throw new IpcError(errorData, status); } } else if (err.code === 'ECONNABORTED') { Logger.error('Request timed out.', err, { context: 'Validation' }); throw new IpcError('Request timed out', 408); } else if ( err.message?.includes('SSL') || err.message?.includes('certificate') || err.code === 'ERR_SSL_CERT' ) { Logger.error('SSL certificate validation failed.', err, { context: 'Validation' }); throw new IpcError( 'SSL certificate validation failed.', 495, 'SSL certificate validation failed.' ); } else if (err.code === 'ENOTFOUND') { Logger.error('Error: Could not resolve host name', err, { context: 'Validation' }); throw new IpcError( 'Error: Could not resolve host name', 404, 'Error: Could not resolve host name' ); } else if (err.code === 'ECONNREFUSED') { Logger.error( 'Error: Gateway refused to connect. Please verify the service availability.', err, { context: 'Validation' } ); throw new IpcError( 'Error: Gateway refused to connect. Please verify the service availability.', 503, 'Error: Gateway refused to connect. Please verify the service availability.' ); } else { Logger.error('Gateway validation failed', err, { context: 'Validation' }); throw new IpcError('Something went wrong while validating the gateway.', 500); } }); } export function ParseAndFindResponse(response: any) { const failedExplanations: string[] = []; if (response?.data?.StudioResult && Array.isArray(response.data.StudioResult)) { for (const item of response.data.StudioResult) { if (item && typeof item === 'object') { const apiKey = Object.keys(item).find((key) => key.toLowerCase() === 'api'); if (apiKey && item[apiKey]) { const api = item[apiKey]; if (api.status === 'Failed' && api.explanation) { failedExplanations.push(api.explanation); } } } } } return failedExplanations; }