Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
3.0 kB
5
Indexable
Never
const Configurapi = require('configurapi');
const oneliner = require('one-liner');
const Adapter = require('./LambdaAdapter');
const AWS = require('aws-sdk');

AWS.config.update({ region: 'us-east-1' });

let decrypted;
const functionName = process.env.AWS_LAMBDA_FUNCTION_NAME;
let env = {};
const kms = new AWS.KMS();

///////////////////////////////////
// Utility functions
///////////////////////////////////
function log(prefix, msg)
{
    let time = new Date().toISOString();
    console.debug(`${time} ${prefix}: ${oneliner(msg)}`); //Use console.debug to exclude "$date $awsRequestId" prefix in CloudWatch logs
}

async function decrypt() {
    if (!decrypted) {
        let promises = [];
        for ( let key of Object.keys(process.env)) {
            promises.push(new Promise(async (resolve, reject) => {
                try {
                    const data = await kms.decrypt({
                        CiphertextBlob: Buffer.from(process.env[key], 'base64'),
                        EncryptionContext: { LambdaFunctionName: functionName },
                    }).promise();
                    env[key] = data.Plaintext.toString('ascii');
                } catch (err) {
                    env[key] = process.env[key];
                }
                resolve(0);
            }));
        }
        await Promise.all(promises);
        decrypted = true;
    }
}


///////////////////////////////////
// Start service
///////////////////////////////////
let service;
let config;
  
///////////////////////////////////
// Entry point
///////////////////////////////////
exports.handler = async (awsEvent, context, callback) => 
{
    await decrypt();
    process.env = env;

    if (!config)
    {
        config = Configurapi.Config.load('./config.yaml');
    }

    if (!service)
    {
        service = new Configurapi.Service(config);
        service.on("trace", (s) => log('Trace', s));
        service.on("debug", (s) => log('Debug', s));
        service.on("error", (s) => log('Error', s));
    }

    try
    {
        let event = new Configurapi.Event(Adapter.toRequest(awsEvent, context));
        event.id = context.awsRequestId;
    
        
        let logWithEvent = (logLevel, event, ...messages) => log(logLevel, `${event ? event.id : ''} - ${event ? event.correlationId : ''} - ${messages.map(message => typeof message === 'string' ? message : JSON.stringify(message)).join(' ')}`);

        console.log = (...messages) => logWithEvent('Trace', event, messages);
        console.error = (...messages) => logWithEvent('Error', event, messages);
        console.warn = console.log;

        await service.process(event);
        
        callback(undefined, Adapter.toResponse(event.response))
    }
    catch(error)
    {
        let response = new Configurapi.ErrorResponse(error, -1);
        
        callback(JSON.stringify(response));
    }
};