英文:
GCP list projects wtih Golang API
问题
我正在尝试学习更多关于Go语言的知识,我的第一个程序是列出我们GCP组织中的所有项目(相当于gcloud projects list
的API等效方式)。之后,我想利用这个程序来创建机器镜像,当计算引擎的标签更新时。
我正在使用Google API文档中的这个样板代码:
"ListProjects列出指定文件夹或组织资源的直接子项目。"
package main
import (
resourcemanager "cloud.google.com/go/resourcemanager/apiv3"
"context"
"google.golang.org/api/iterator"
resourcemanagerpb "google.golang.org/genproto/googleapis/cloud/resourcemanager/v3"
)
func main() {
ctx := context.Background()
c, err := resourcemanager.NewProjectsClient(ctx)
if err != nil {
// TODO: 处理错误。
}
defer c.Close()
req := &resourcemanagerpb.ListProjectsRequest{
// TODO: 填充请求结构体字段。
// 参见 https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/resourcemanager/v3#ListProjectsRequest。
}
it := c.ListProjects(ctx, req)
for {
resp, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
// TODO: 处理错误。
}
// TODO: 使用 resp。
_ = resp
}
}
我意识到这里有一些未完成的"TODO"部分。有人可以帮忙建议如何使用这个样板代码来获取项目的简单列表吗?感觉我缺少一种方式来标识我的组织或项目,但由于我想要获取整个项目列表,似乎在API调用中没有传递我的组织ID?
目前我得到的错误是"PermissionDenied desc = The caller does not have permission"。然而,我知道我已经设置了Google应用程序默认凭据,因为我可以使用另一个Go API调用来列出计算实例。
英文:
I am trying to learn more Go, and my first program is to list all the projects in our GCP org (API equivalent of gcloud projects list
). Later I want to take this as a springboard to create machine images when a Compute Engine label is updated.
I am using this boilplate from the Google API docs:
"ListProjects lists projects that are direct children of the specified folder or organization resource."
package main
import (
resourcemanager "cloud.google.com/go/resourcemanager/apiv3"
"context"
"google.golang.org/api/iterator"
resourcemanagerpb "google.golang.org/genproto/googleapis/cloud/resourcemanager/v3"
)
func main() {
ctx := context.Background()
c, err := resourcemanager.NewProjectsClient(ctx)
if err != nil {
// TODO: Handle error.
}
defer c.Close()
req := &resourcemanagerpb.ListProjectsRequest{
// TODO: Fill request struct fields.
// See https://pkg.go.dev/google.golang.org/genproto/googleapis/cloud/resourcemanager/v3#ListProjectsRequest.
}
it := c.ListProjects(ctx, req)
for {
resp, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
// TODO: Handle error.
}
// TODO: Use resp.
_ = resp
}
}
I realize there are "TODO" pieces here that I don't have completed. Can someone help to suggest how I can take this boilplate and get a simple list of projects? It feels like I am lacking some form of identifying my org or my project, but since I want the entire list of projects, it seems like I am not conveying my org id in the API call?
For now I am getting "PermissionDenied desc = The caller does not have permission". However, I know that I have Google Application Default credentials setup because I can do another API call in go to list compute instances.
答案1
得分: 2
使用APIs Explorer来调用Cloud Resource Manager API v3的projects.search
方法。
ORGANIZATION=[[YOUR-ORG]]
PROJECT=[[YOUR-PROJECT]] # Service Accounts are owned by Projects
ACCOUNT="tester"
# 在项目中启用Cloud Resource Manager API
# 这个项目也将拥有Service Account
gcloud services enable cloudresourcemanager.googleapis.com \
--project=${PROJECT}
# 创建Service Account
gcloud iam service-accounts create ${ACCOUNT} \
--project=${PROJECT}
EMAIL=${ACCOUNT}@${PROJECT}.iam.gserviceaccount.com
# 在本地创建Service Account Key
# 仅用于测试目的
gcloud iam service-accounts keys create ${PWD}/${ACCOUNT}.json \
--iam-account=${EMAIL} \
--project=${PROJECT}
# 确保Service Account可以浏览组织的资源
gcloud organizations add-iam-policy-binding ${ORGANIZATION} \
--role=roles/browser \
--member=serviceAccount:${EMAIL}
export GOOGLE_APPLICATION_CREDENTIALS=${PWD}/${ACCOUNT}.json
export ORGANIZATION
go run .
还有:
main.go
:
package main
import (
"context"
"fmt"
"log"
"os"
resourcemanager "cloud.google.com/go/resourcemanager/apiv3"
resourcemanagerpb "google.golang.org/genproto/googleapis/cloud/resourcemanager/v3"
"google.golang.org/api/iterator"
)
func main() {
organization := os.Getenv("ORGANIZATION")
if organization == "" {
log.Fatalf("无法从环境中获取ORGANIZATION")
}
ctx := context.Background()
c, err := resourcemanager.NewProjectsClient(ctx)
if err != nil {
log.Fatal(err)
}
defer c.Close()
rqst := &resourcemanagerpb.SearchProjectsRequest{
Query: fmt.Sprintf("parent:organizations/%s", organization),
}
it := c.SearchProjects(ctx, rqst)
for {
resp, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Fatal(err)
}
log.Println(resp.DisplayName)
}
}
以上是要翻译的内容。
英文:
Using APIs Explorer for Cloud Resource Manager API v3 projects.search
ORGANIZATION=[[YOUR-ORG]]
PROJECT=[[YOUR-PROJECT]] # Service Accounts are owned by Projects
ACCOUNT="tester"
# Enable Cloud Resource Manager API in a Project
# This Project will own the Service Account too
gcloud services enable cloudresourcemanager.googleapis.com \
--project=${PROJECT}
# Create the Service Account
gcloud iam service-accounts create ${ACCOUNT} \
--project=${PROJECT}
EMAIL=${ACCOUNT}@${PROJECT}.iam.gserviceaccount.com
# Create a Service Account Key locally
# For testing purposes only
gcloud iam service-accounts keys create ${PWD}/${ACCOUNT}.json \
--iam-account=${EMAIL} \
--project=${PROJECT}
# Ensure the Service Account can browse the Organization's resources
gcloud organizations add-iam-policy-binding ${ORGANIZATION} \
--role=roles/browser \
--member=serviceAccount:${EMAIL}
export GOOGLE_APPLICATION_CREDENTIALS=${PWD}/${ACCOUNT}.json
export ORGANIZATION
go run .
And:
main.go
:
package main
import (
"context"
"fmt"
"log"
"os"
resourcemanager "cloud.google.com/go/resourcemanager/apiv3"
resourcemanagerpb "google.golang.org/genproto/googleapis/cloud/resourcemanager/v3"
"google.golang.org/api/iterator"
)
func main() {
organization := os.Getenv("ORGANIZATION")
if organization == "" {
log.Fatalf("unable to obtain ORGANIZATION from the environment")
}
ctx := context.Background()
c, err := resourcemanager.NewProjectsClient(ctx)
if err != nil {
log.Fatal(err)
}
defer c.Close()
rqst := &resourcemanagerpb.SearchProjectsRequest{
Query: fmt.Sprintf("parent:organizations/%s", organization),
}
it := c.SearchProjects(ctx, rqst)
for {
resp, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Fatal(err)
}
log.Println(resp.DisplayName)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论