繁体   English   中英

用于本地开发的 Google Cloud Functions 凭据

[英]Google Cloud Functions Credentials for Local Development

我有一个谷歌云 function。 在这个 function 中,我想将文件写入 GCS(谷歌云存储),然后获取写入 GCS 的文件的签名 URL 并将该 ZE6B391A8D2C4D45902A23A8B6DZ 发送给调用者。

对于本地开发,我使用 functions-framework 命令在本地运行函数: functions-framework --source=.build/ --target=http-function --port 8082

当我想写入 GCS 或获取已签名的 URL 时,云功能框架只是尝试从已登录的 gcloud CLI 用户那里获取凭据。 但是,我想指出它从服务帐户中读取凭据。 对于所有其他 gcloud 开发目的,我们已将服务帐户信息放在本地 creds.json 文件中,并将 gcloud 指向从该文件中读取。

有什么方法可以实现这个功能吗? 这意味着当我在本地启动函数(使用函数框架)时,我将它指向 creds.json 文件以从那里读取凭据?

所有 Google 的 SDK,例如用于 GCS,都使用您应该使用的应用程序默认凭据,而不是显式路径到密钥。 如果函数框架是这样,那么导出变量应该可以工作。

在这种情况下,命令gcloud auth application-default login是更好的建议,特别是对于测试签名的 URL,因为使用该本地凭据以及 Cloud Functions 凭据(通过元数据服务器),私钥不存在,并且必须以特定方式调用已签名的 URL(提供令牌和服务帐户才能对 URL 进行签名)。 使用gcloud auth application-default login创建应用程序默认凭据,该凭据具有用户帐户的所有权限,并作为名为{HOME}/.config/gcloud/application-default_credentials的密钥持久保存。

云 Function 本地开发认证

这就是我正在使用由发布/订阅事件触发的 Nodejs 本地开发谷歌云 function 所做的。 这使用了函数框架 Nodejs

TL;博士;

# shell A
gcloud auth application-default login

npm start

发布/订阅事件消息

# shell B
curl -d "@mockPubSub.json" \                                                                                
  -X POST \
  -H "Content-Type: application/json" \
  http://localhost:8080

更多细节

  1. Cloud Function 与功能框架

文档: 函数框架 Nodejs

package.json

注意--target--signature-type

{
...
  "scripts": {
    "start": "npx functions-framework --target=helloPubSub --signatur-type=event"
  },
  "dependencies": {
    "@google-cloud/debug-agent": "^7.0.0",
    "@google-cloud/storage": "^6.0.0"
  },
  "devDependencies": {
    "@google-cloud/functions-framework": "^3.1.2"
  }
...
}
  1. 下载文件的示例nodejs cloud function
/* modified from the sample
index.js
*/

const {Storage} = require('@google-cloud/storage');

function log(message, severity = 'DEBUG', payload) {
  // Structured logging
  // https://cloud.google.com/functions/docs/monitoring/logging#writing_structured_logs

  if (!!payload) {
    // If payload is an Error, get the stack trace.
    if (payload instanceof Error && !!payload.stack) {
      if (!!message ) {
         message = message + '\n' + payload.stack;
      } else {
         message = payload.stack;
      }
    }
  }
  const logEntry = {
    message: message,
    severity: severity,
    payload : payload
  };
  console.log(JSON.stringify(logEntry));
}

function getConfigFile(payload){
  console.log("Get Config File from GCS")
  const bucketName = 'some-bucket-in-a-project';
  const fileName = 'config.json';

  // Creates a client
  const storage = new Storage();

  async function downloadIntoMemory() {
    // Downloads the file into a buffer in memory.
    const contents = await storage.bucket(bucketName).file(fileName).download();

    console.log(
      `Contents of gs://${bucketName}/${fileName} are ${contents.toString()}.`
    );
  }

  downloadIntoMemory().catch(console.error);
}


exports.helloPubSub = async (pubSubEvent, context) => {
  /*
  Read payload from the event and log the exception in App project if the payload cannot be parsed
  */
 try {
    const payload = Buffer.from(pubSubEvent.body.message.data, 'base64').toString()
    const pubSubEventObj = JSON.parse(payload) ;
    console.log("name: ", pubSubEventObj.name);

    getConfigFile(pubSubEventObj)

  } catch (err) {
    log('failed to process payload: + payload \n' , 'ERROR', err);
  }

};
  1. Pub/Sub 事件的模拟消息

博客参考,但我没有使用模拟器

myJson.json

{"widget": {
    "debug": "on",
    "window": {
        "title": "Sample Konfabulator Widget",
        "name": "main_window",
        "width": 500,
        "height": 500
    },
    "image": { 
        "src": "Images/Sun.png",
        "name": "sun1",
        "hOffset": 250,
        "vOffset": 250,
        "alignment": "center"
    },
    "text": {
        "data": "Click Here",
        "size": 36,
        "style": "bold",
        "name": "text1",
        "hOffset": 250,
        "vOffset": 100,
        "alignment": "center",
        "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
    }
}}  
  1. 为 Pub/sub 消息编码(可能有更好的方法
cat myJson.json | grep -v % | base64
  1. 取 output 并将其放入数据键的值中:

mockPubSub.json

{
  "message": {
    "attributes": {
      "greeting": "Hello from the Cloud Pub/Sub Emulator!"
    },
    "data": "< put the output of the base64 from above here >",
    "messageId": "136969346945"
  },
  "subscription": "projects/myproject/subscriptions/mysubscription"
}
  1. 遵循TL;DR:以上的步骤。

免责声明

  • gcloud auth application-default login使用执行命令的用户的权限。 所以请记住,在生产中,云 function 使用的服务帐户将需要从存储桶中读取。
  • 在擦洗这个(即重命名位)并复制它时,我可能把它搞砸了。 对不起,如果这是真的。
  • 如果您好奇,这都是人为的,我的设计是从云调度程序中获取消息,其中包含有关从配置中读取内容的相关详细信息。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM