import * as os from 'os' ; import * as fs from 'fs' ; import * as zlib from 'zlib' ; import * as stream from 'stream' ; import { v4 as uuid } from 'uuid' ; import { remote } from 'electron' ; import * as utils from '../utils' ; import * as AWS from 'aws-sdk' ; import sanitize from 'sanitize-filename' ; import { LogGroup , LogStream , Settings } from '../common-interfaces' ; import * as storage from 'electron-json-storage' ; import * as constants from '../constants' ; const dialog = remote . dialog ; export function applicationPassphrase ( ) { let seed = utils . hash ( os . type ( ) + os . hostname ( ) + 'ufQROog1Q8' ) ; return utils . random ( seed , 100000000000 , 1000000000000 ) . toString ( 36 ) . slice ( 0 , 8 ) + '_xiONGor6G9!' ; } export function createUuid ( ) { let id = uuid ( ) ; return id ; } export function currentDate ( ) { return new Date ( ) ; } export function save ( settings ) { let crypted = { region : settings . region , awsAccessKeyId : utils . encrypt ( settings . awsAccessKeyId , applicationPassphrase ( ) ) , awsSecretAccessKey : utils . encrypt ( settings . awsSecretAccessKey , applicationPassphrase ( ) ) , lineBreak : settings . lineBreak , filters : settings . filters , } ; storage . set ( 'aws' , crypted , ( err ) => console . log ( err ) ) ; } export function load ( ) { let decrypted = ( settings ) => { return { region : settings . region , awsAccessKeyId : utils . decrypt ( settings . awsAccessKeyId , applicationPassphrase ( ) ) , awsSecretAccessKey : utils . decrypt ( settings . awsSecretAccessKey , applicationPassphrase ( ) ) , lineBreak : settings . lineBreak , filters : settings . filters , } ; } ; return new Promise < Settings > ( ( resolve , reject ) => { storage . get ( 'aws' , ( error , data ) => { if ( error ) { reject ( error ) ; } else { let settings = { region : ( typeof data . region === 'string' ) ? data . region : constants . Region . AP_NORTHEAST_1 , awsAccessKeyId : ( typeof data . awsAccessKeyId === 'string' ) ? data . awsAccessKeyId : '' , awsSecretAccessKey : ( typeof data . awsSecretAccessKey === 'string' ) ? data . awsSecretAccessKey : '' , lineBreak : ( typeof data . lineBreak === 'string' ) ? data . lineBreak : constants . LineBreak . LF , filters : ( Array . isArray ( data . filters ) ) ? data . filters : [ ] , } ; resolve ( decrypted ( settings ) ) ; } } ) ; } ) ; } export function showSaveDialog ( fileName ? ) { let filePath = dialog . showSaveDialog ( { defaultPath : fileName ? sanitize ( fileName ) : undefined , filters : [ { name : 'Raw Text' , extensions : [ 'txt' ] } , { name : 'GZip' , extensions : [ 'gz' ] } , ] , } ) ; if ( ! filePath ) { return undefined ; } let out = fs . createWriteStream ( filePath ) ; if ( filePath . endsWith ( '.gz' ) ) { let gzip = zlib . createGzip ( ) ; gzip . pipe ( out ) ; return gzip ; } return out ; } export function getCloudWatchLogGroups ( cloudwatchlogs , callbackStart , callbackError , callbackEnd , retryDelay = 1000 ) { callbackStart ( new Date ( ) ) ; let fetchRecursively = ( groups , nextToken ? , retry = 3 ) => { cloudwatchlogs . describeLogGroups ( { nextToken } , ( err , data ) => { let now = new Date ( ) ; if ( err ) { if ( retry > 0 ) { setTimeout ( ( ) => fetchRecursively ( groups , nextToken , retry - 1 ) , retryDelay ) ; return ; } callbackError ( now , err ) ; return ; } if ( ! data . logGroups ) { callbackEnd ( now , groups ) ; return ; } let part = data . logGroups . filter ( g => g . arn != null ) . filter ( g => g . logGroupName != null ) . filter ( g => g . creationTime != null ) . filter ( g => g . storedBytes != null ) . map ( g => ( { arn : g . arn ! , logGroupName : g . logGroupName ! , creationTime : g . creationTime ! , storedBytes : g . storedBytes ! , } ) ) ; let merged = groups . concat ( part ) ; if ( ! data . nextToken ) { callbackEnd ( now , merged ) ; return ; } fetchRecursively ( merged , data . nextToken ) ; } ) ; } ; fetchRecursively ( [ ] ) ; } export function getCloudWatchLogStreams ( cloudwatchlogs , logGroupName , callbackStart , callbackError , callbackEnd , retryDelay = 1000 ) { callbackStart ( new Date ( ) ) ; let fetchRecursively = ( streams , nextToken ? , retry = 3 ) => { cloudwatchlogs . describeLogStreams ( { logGroupName , descending : true , orderBy : 'LastEventTime' , nextToken } , ( err , data ) => { let now = new Date ( ) ; if ( err ) { if ( retry > 0 ) { setTimeout ( ( ) => fetchRecursively ( streams , nextToken , retry - 1 ) , retryDelay ) ; return ; } callbackError ( now , err ) ; return ; } if ( ! data . logStreams ) { callbackEnd ( now , streams ) ; return ; } let part = data . logStreams . filter ( g => typeof g . arn != null ) . filter ( g => g . logStreamName != null ) . filter ( g => g . creationTime != null ) . filter ( g => g . firstEventTimestamp != null ) . filter ( g => g . lastEventTimestamp != null ) . filter ( g => g . storedBytes != null ) . map ( g => ( { arn : g . arn ! , logStreamName : g . logStreamName ! , creationTime : g . creationTime ! , firstEventTimestamp : g . firstEventTimestamp ! , lastEventTimestamp : g . lastEventTimestamp ! , storedBytes : g . storedBytes ! , } ) ) ; let merged = streams . concat ( part ) ; if ( ! data . nextToken ) { callbackEnd ( now , merged ) ; return ; } fetchRecursively ( merged , data . nextToken ) ; } ) ; } ; fetchRecursively ( [ ] ) ; } export function getCloudWatchLogsEvents ( cloudwatchlogs , logGroupName , logStreamName , startDate , endDate , callbackData , callbackError , callbackEnd , startFromHead = true , limit ? , retryDelay = 2000 ) { let createParams = ( nextToken ? ) => { return { logGroupName : logGroupName , logStreamName : logStreamName , startTime : startDate . getTime ( ) , endTime : endDate . getTime ( ) , limit : limit , nextToken : nextToken , startFromHead : startFromHead , } ; } ; let fetchRecursively = ( nextToken ? , retry = 3 ) => { cloudwatchlogs . getLogEvents ( createParams ( nextToken ) , ( err , data ) => { if ( err ) { if ( retry > 0 ) { setTimeout ( ( ) => fetchRecursively ( nextToken , retry - 1 ) , retryDelay ) ; return ; } callbackError ( err ) ; return ; } let latestToken = data . nextForwardToken ; if ( ! latestToken || nextToken === latestToken ) { callbackEnd ( ) ; return ; } if ( data . events && data . events . length > 0 ) { let latestTimestamp = data . events [ data . events . length - 1 ] . timestamp ; let progress = latestTimestamp ? utils . progressAt ( new Date ( latestTimestamp ) , startDate , endDate ) : 0 ; callbackData ( data , progress ) ; } if ( limit ) { callbackEnd ( ) ; return ; } fetchRecursively ( latestToken ) ; } ) ; } ; fetchRecursively ( ) ; } export function connectCloudWatchLogs ( settings ) { return new AWS . CloudWatchLogs ( { region : settings . region , accessKeyId : settings . awsAccessKeyId , secretAccessKey : settings . awsSecretAccessKey , } ) ; }