[英]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
的密钥持久保存。
这就是我正在使用由发布/订阅事件触发的 Nodejs 本地开发谷歌云 function 所做的。 这使用了函数框架 Nodejs
# 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
文档: 函数框架 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"
}
...
}
/* 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);
}
};
博客参考,但我没有使用模拟器
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;"
}
}}
cat myJson.json | grep -v % | base64
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"
}
gcloud auth application-default login
使用执行命令的用户的权限。 所以请记住,在生产中,云 function 使用的服务帐户将需要从存储桶中读取。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.