import { CloudWatchLogsClient } from '@aws-sdk/client-cloudwatch-logs'; import { CloudTrailClient } from '@aws-sdk/client-cloudtrail'; import { loadEnvConfig } from './env.js'; import { createCredentialProvider, detectCredentialProviderType, validateCredentials } from './aws-credentials.js'; import { getLogger } from '../utils/logging.js'; import { ConfigurationError } from '../utils/error-handling.js'; const logger = getLogger(); // Shared AWS clients export let cloudWatchLogsClient: CloudWatchLogsClient; export let cloudTrailClient: CloudTrailClient; // Track if clients have been initialized let initialized = false; let credentialsValidated = false; /** * Initialize AWS clients with secure credential handling * @param validateCreds Whether to validate credentials before initializing clients * @returns Object containing initialized AWS clients */ export async function initializeAwsClients(validateCreds = true) { try { // If already initialized, just return the clients if (initialized && cloudWatchLogsClient && cloudTrailClient) { return { cloudWatchLogsClient, cloudTrailClient }; } const config = loadEnvConfig(); const region = config.AWS_REGION; // Detect and create appropriate credential provider const providerType = detectCredentialProviderType(); logger.info(`Using AWS credential provider: ${providerType}`); const credentials = createCredentialProvider(providerType); // Validate credentials if requested if (validateCreds && !credentialsValidated) { logger.info('Validating AWS credentials...'); const validationResult = await validateCredentials(region); if (!validationResult.valid) { throw new ConfigurationError( validationResult.message || 'AWS credentials validation failed', 'AWS_CREDENTIALS', validationResult.error ); } logger.info('AWS credentials validated successfully', { accountId: validationResult.accountId, arn: validationResult.arn }); credentialsValidated = true; } // Initialize the AWS clients with the provided configuration and credentials const clientConfig = { region, credentials, // Add reasonable timeouts to prevent hanging operations requestHandler: { connectionTimeout: 5000, // 5 seconds socketTimeout: 10000 // 10 seconds } }; cloudWatchLogsClient = new CloudWatchLogsClient(clientConfig); cloudTrailClient = new CloudTrailClient(clientConfig); logger.info(`AWS clients initialized for region: ${region}`); initialized = true; return { cloudWatchLogsClient, cloudTrailClient }; } catch (error) { logger.error('Error initializing AWS clients:', error); if (error instanceof ConfigurationError) { throw error; } throw new ConfigurationError( `Failed to initialize AWS clients: ${error instanceof Error ? error.message : String(error)}`, 'AWS_CLIENT_INITIALIZATION', error ); } }