从API调用返回到AWS Secrets Manager之后,将数据导出到节点文件中

时间:2018-10-15 22:28:18

标签: javascript node.js

背景

我正在秘密管理器中存储AWS中RDS的数据库信息。我正在使用AWS-SDK检索密码和其他数据,因此可以在运行时创建secrets对象。当我尝试创建此对象然后将其导出时,导出的对象始终缺少我希望从aws-sdk返回的数据。

我尝试过的内容-

我尝试使用async await,但是在正确填充所有数据之前,它仍在导出对象。

示例

const AWS = require('aws-sdk');
const region = 'us-west-2';
const secretName = 'example/example/example';
let secrets = {
  username: '',
  password: '',
  host: '',
  port: '',
  database: '',
  email: 'example@example.com',
  emailPassword: 'SomePassword'
};

const client = new AWS.SecretsManager({
  region: region
});

client.getSecretValue({ SecretId: secretName }, async (err, data) => {
  if (err) {
    throw err;
  } else {
    const res = await JSON.parse(data.SecretString);
    secrets.username = res.username;
    secrets.password = res.password;
    secrets.host = res.host;
    secrets.port = res.port;
    secrets.database = res.database;
  }
});

module.exports = secrets;

问题

这里明显的问题是不能正确创建承诺,但是我不确定为什么导出文件后我的尝试会完成承诺。如果在某些情况下我console.log(secrets)在另一个文件中,它将输出缺少对象的数据,然后在我console.log(secrets)在函数内部几秒钟后,显示诺言返回的数据。

从AWS返回数据并将其添加到对象secrets之后,构建该对象secrets并将其导出的正确方法是什么?

2 个答案:

答案 0 :(得分:1)

根据docsgetSecretValue的第二个参数是一个回调函数,因此无需使用async / await,因为async / await可以与promises一起使用。

删除异步/等待应该可以。

client.getSecretValue({ SecretId: secretName }, (err, data) => {
  if (err) {
    throw err;
  } else {
    const res = JSON.parse(data.SecretString);
    secrets.username = res.username;
    secrets.password = res.password;
    secrets.host = res.host;
    secrets.port = res.port;
    secrets.database = res.database;
  }
}); 

但是,您正在同步导出secrets对象,并且其属性已异步设置。

相反,您可以返回承诺供其他模块使用。

const AWS = require('aws-sdk');
const region = 'us-west-2';
const secretName = 'example/example/example';
let secrets = {
  email: 'example@example.com',
  emailPassword: 'SomePassword'
};

const client = new AWS.SecretsManager({
  region: region
});

const promise = new Promise((resolve, reject) => {
  client.getSecretValue({ SecretId: secretName }, async (err, data) => {
    if (err) {
      reject(err);
    } else {
      const res = await JSON.parse(data.SecretString);
      secrets.username = res.username;
      secrets.password = res.password;
      secrets.host = res.host;
      secrets.port = res.port;
      secrets.database = res.database;
      resolve(secrets);
    }
  });
})

module.exports = promise;

然后,在使用该模块的其他模块中,您可以使用async / await,因为我们现在有了诺言。

import {promise} from "./this-module";

(async () => {
  const secrets = await promise;
  console.log(secrets);
})();

更新

我不确定这是否行得通,但是值得一试。在此,仅在设置了module.exports之后才设置secrets。如果这不起作用,那么我将在StackOverflow上问一个新问题,即如何使用CommonJS(您正在使用的模块格式)导出已解决的Promise。

const AWS = require('aws-sdk');
const region = 'us-west-2';
const secretName = 'example/example/example';
let secrets = {
  email: 'example@example.com',
  emailPassword: 'SomePassword'
};

const client = new AWS.SecretsManager({
  region: region
});

const promise = new Promise((resolve, reject) => {
  client.getSecretValue({ SecretId: secretName }, async (err, data) => {
    if (err) {
      reject(err);
    } else {
      const res = await JSON.parse(data.SecretString);
      secrets.username = res.username;
      secrets.password = res.password;
      secrets.host = res.host;
      secrets.port = res.port;
      secrets.database = res.database;
      resolve(secrets);
    }
  });
});

(async () => {
  module.exports = await promise;
})();

答案 1 :(得分:0)

client.getSecretValue({ SecretId: secretName     }).subscribe(data=>{
    const res =JSON.parse(data.SecretString);
    secrets.username = res.username;
    secrets.password = res.password;
    secrets.host = res.host;
    secrets.port = res.port;
    secrets.database = res.database;
  });