使用GCP服务账号通过Node.js获取结算账号列表返回空数组问题咨询
问题原因及解决方案
1. 权限配置错误
你当前给服务账号配置的Billing Account Usage Commitment Recommender Viewer角色不满足接口调用要求:
- 该角色仅拥有结算账号使用承诺推荐相关的只读权限,没有列出结算账号的权限
- 要正常调用
listBillingAccounts接口,需要给服务账号授予Billing Account Viewer角色,该角色包含billing.accounts.list核心权限,匹配你配置的cloud-billing.readonlyOAuth scope
2. 授权层级与调用参数适配问题
即使权限配置正确,也要注意调用逻辑和授权层级匹配:
- 如果你调用的是不带
project参数的接口:返回的是服务账号在结算账号层级直接被授权的所有结算账号。如果仅在项目层级给服务账号授予权限,该接口会返回空数组,需要在组织或目标结算账号层级给服务账号授予对应角色 - 如果你调用的是带
project参数的接口:该接口仅返回绑定到指定项目的单个结算账号信息,需要确认你传入的是项目ID而非项目显示名,且服务账号在该项目下拥有billing.projects.getInfo权限
3. 代码存在变量作用域问题
你提供的代码存在变量作用域错误,可能会导致逻辑异常:accounts变量仅在if/else块内定义,块外访问时会触发引用错误,建议调整代码如下:
async function listBillingAccounts(project) { let keys = JSON.parse(Buffer.from(process.env.SERVICE_ACCOUNT_BASE64_JSON, "base64").toString("ascii")); const client = new CloudBillingClient({credentials : keys}); // 将accounts定义提到块外 let accounts; if (project !== undefined) { [accounts] = await client.listBillingAccounts({ project, }); console.log(accounts); } else { [accounts] = await client.listBillingAccounts({}); console.log(accounts); } console.info(`found ${accounts.length} billing accounts:`); for (const account of accounts) { console.info(`${account.displayName}:`); console.info(` open: ${account.open}`); console.info(` parentBillingAccount: ${account.masterBillingAccount}`); } }
内容的提问来源于stack exchange,提问作者delucaezequiel
相关产品推荐
相关产品推荐

