Как получить доступ к хранилищу параметров aws из лямбды, используя node.js и aws-sdk - PullRequest
0 голосов
/ 21 февраля 2019

Я создал шаблон формирования лямбды и облака, который предоставляет лямбда-доступ к хранилищу параметров и диспетчеру секретов.Когда я тестирую лямбду, у меня есть следующие функции вне функции export.handler:

function getParameterFromStore(param){
    let promise = new Promise(function(resolve, reject){
        console.log('++ ' + param.Path);
        servmgr.getParametersByPath(param, function(err, data){
            if(err){
                reject(console.log('Error getting parameter: ' + err, err.stack));
            } else {
                resolve(data);
            }
        });
    });

   let parameterResult = promise.then(function(result){
    console.log('---- result: '+ JSON.stringify(result));
        return result;
    });
   return parameterResult;
};

servmgr создается как var servmgr = new AWS.SSM();

Когда я вызываю эту функцию из экспорта.handler-функцию я делаю так:

myFirstParam =  { Path : '/myPath/Service/servicesEndpoint'};

let endpointResult = getParameterFromStore(myFirstParam);

В лямбда-функции у меня есть функция получения параметра, определенного вне функции export.handler, заключенного в обещание.

Когда я запускаю/ проверить эту лямбду, возвращаемый объект всегда неопределен ... Я получаю параметры [] обратно, но без значений.

2019-02-20T21:42:41.340Z    2684fe88-d552-4560-a477-6761f2de6717    ++ /myPath/Service/serviceEndpoint
2019-02-20T21:42:41.452Z    2684fe88-d552-4560-a477-6761f2de6717    ---- result: {"Parameters":[]}

Как вы получаете значения параметров, возвращаемые лямбда во время выполнения?

обновление

, основанное на предложении / ответе Фалеса, я упростил лямбду до этого:

const getParameterFromStoreAsync = (param) => {
    return new Promise((resolve, reject) => {
        servmgr.getParametersByPath(param, (err, data) => {
            if(err){
                reject(console.log('Error getting parameter: ' + err, err.stack));
            } 
            return resolve(data);
        });
    });
};

exports.handler = async(event, ctx, callback) => {

console.log('INFO[lambda]: Event: [' + JSON.stringify(event, null, 2) + ']');

    console.log('this is the event' + JSON.stringify(event));
    sfdcEndPointParam =  { Path : '/PartnerBanking/Service/SfdcEndpoint'};
    let myendpoint = await getParameterFromStoreAsync(sfdcEndPointParam);

    console.log('### endpoint path: ' + JSON.stringify(myendpoint));

done = ()=>{}
callback(null, done());
};

Я все еще вижув моих тестах возвращается пустой массив:

### endpoint path: {"Parameters":[]}

Я также переместил функцию в функцию обратного вызова как

exports.handler = (event,ctx, callback){
done = async()=>{
 console.log('this is the event' + JSON.stringify(event));
    sfdcEndPointParam =  { Path : '/PartnerBanking/Service/SfdcEndpoint'};
    let myendpoint = await getParameterFromStoreAsync(sfdcEndPointParam);

    console.log('### endpoint path: ' + JSON.stringify(myendpoint));}
}
callback(null, done());

Тот же результат ... пустой массив.Какие-нибудь дополнительные вещи попробовать?

1 Ответ

0 голосов
/ 21 февраля 2019

Это потому, что ваш getParameterFromStore возвращается до выполнения кода then(), поэтому parameterResult равно undefined.Если вы не хотите слишком сильно изменять свой код, я бы вернул созданное вами обещание, например:

function getParameterFromStore(param){
return new Promise(function(resolve, reject){
    console.log('++ ' + param.Path);
    servmgr.getParametersByPath(param, function(err, data){
        if(err){
            reject(console.log('Error getting parameter: ' + err, err.stack));
        } else {
            resolve(data);
        }
    });
});

};

И, наконец, на клиенте вашей функции выможно получить такой результат:

const myFirstParam =  { Path : '/myPath/Service/servicesEndpoint'}
getParameterFromStore(myFirstParam).then(console.log)

При кодировании в NodeJS, однако, я настоятельно рекомендую вместо этого использовать async / await , чтобы вы могли избежать Обетованного ада(chaninig Promise после Promise для достижения чего-то «синхронно»)

При использовании async / await вы можете создавать свой код, как если бы он был синхронным.Вот реорганизованная версия вашего примера с использованием функций async / await и стрелок:

const getParameterFromStore = param => {
    return new Promise((resolve, reject) => {
        console.log('++ ' + param.Path);
        servmgr.getParametersByPath(param, (err, data) => {
            if (err) {
                console.log('Error getting parameter: ' + err, err.stack)
                return reject(err);
            }
            return resolve(data);
        });
    })
}

exports.handler = async (event) => {
   const endpointResult = await getParameterFromStore(event.someAttributeFromTheEventThatYouWantToUse)

   console.log(endpointResult)
};

EDIT : после того, как OP исправил первую проблему, ясоздал рабочий пример самостоятельно.Оказалось, что способ, которым OP вызывал API, был неправильным.

Вот полный рабочий пример:

'use strict';

const AWS = require('aws-sdk')

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

const parameterStore = new AWS.SSM()

const getParam = param => {
  return new Promise((res, rej) => {
    parameterStore.getParameter({
      Name: param
    }, (err, data) => {
        if (err) {
          return rej(err)
        }
        return res(data)
    })
  })
}

module.exports.get = async (event, context) => {
  const param = await getParam('MyTestParameter')
  console.log(param);
  return {
    statusCode: 200,
    body: JSON.stringify(param)
  };
};

Помните атрибут Name, который должен быть предоставлен как частьВызов API для метода ServiceManager.getAttribute.

Этот атрибут указан в официальных документах

Я сам выполнил это, и вот вывод в журналах CloudWatch:

enter image description here

Как видите, значение было успешно возвращено.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...