使用GCP Resource Manager Python V3 API设置IAM Policy失败求助
解决GCP IAM Policy更新失败的问题
直接给你修正后的可运行代码,再拆解问题点:
from google.cloud import resourcemanager_v3 from google.iam.v1 import iam_policy_pb2, policy_pb2 client = resourcemanager_v3.ProjectsClient(credentials=credentials) # 获取当前IAM Policy(直接操作proto对象,不要转字典) req = iam_policy_pb2.GetIamPolicyRequest( resource="projects/mse-sandbox-registry-anushka" ) policy = client.get_iam_policy(request=req) projects_to_add = [] for proj in proj_numbers: account = f"serviceAccount:service-{proj}@serverless-robot-prod.iam.gserviceaccount.com" if proj not in storage_obj_viewer_list: projects_to_add.append(account) # 处理角色绑定:找到对应角色或新建绑定 role_found = False for binding in policy.bindings: if binding.role == "roles/storage.objectViewer": # 用extend添加多个成员,避免嵌套列表 binding.members.extend(projects_to_add) role_found = True break # 如果没有找到该角色的绑定,新建一个 if not role_found: new_binding = policy_pb2.Binding() new_binding.role = "roles/storage.objectViewer" new_binding.members.extend(projects_to_add) policy.bindings.append(new_binding) # 构造Set请求,传入正确的resource格式和proto Policy对象 set_req = iam_policy_pb2.SetIamPolicyRequest( resource="projects/mse-sandbox-registry-anushka", policy=policy ) response = client.set_iam_policy(request=set_req)
原代码的核心错误点:
错误1:用字典代替proto对象传递
MessageToDict把Policy转成字典后,SetIamPolicyRequest无法直接识别这个字典,必须传递原生的policy_pb2.Policy对象。直接操作从get_iam_policy返回的proto对象即可,不需要转字典。错误2:成员列表嵌套问题
members_list.append(projects_to_add)会把整个列表作为单个元素加入成员列表,导致GCP识别无效。改用extend可以把列表里的每个成员逐个添加进去。错误3:Resource参数格式错误
SetIamPolicyRequest的resource必须是projects/{project-id}的完整格式,不能只传项目名。错误4:未处理角色不存在的情况
如果当前Policy里没有roles/storage.objectViewer的绑定,原代码不会新建这个绑定,导致添加操作无效果。新增判断逻辑,不存在时创建新的Binding。
内容的提问来源于stack exchange,提问作者Anushka Vijay
相关产品推荐
相关产品推荐

