如何使用 Google 云 API(直接或使用 GCP PHP 客户端 SDK)以编程方式从 GCP 项目中列出、添加和删除用户?
How do I use the Google Cloud APIs (directly or using the GCP PHP Client SDK) to List, Add, and Remove Users from a GCP project programmatically?
简要总结:我有一个 PHP 网络应用程序,它使用 Google 云 PHP 客户端 SDK 与 Dialogflow 集成。那没问题。我现在需要让我的用户直接访问 GCP Dialogflow 仪表板,这部分意味着他们需要能够 add/remove 从我的应用程序中向用户授予 Dialogflow 权限。 (出于显而易见的原因,我不想给他们完整的项目 IAM 权限和访问权限)。
显然,权限由单独的“Google APIs PHP 的客户端库”处理。
这似乎是用于列出现有项目用户策略的 API:https://cloud.google.com/resource-manager/reference/rest/v1/projects/listOrgPolicies
我认为这是 add/remove 用户部分的 API,但不是那么明显:https://cloud.google.com/resource-manager/reference/rest/v1/projects/setIamPolicy
===
问题:
但是,当我 运行 上面引用的 listOrgPolicies API 中提供的示例代码时,我得到这个错误:
PHP Fatal error: Uncaught Error: Class 'Google_Service_CloudResourceManager_ListOrgPoliciesRequest' not found
composer require google/apiclient-services
和 composer require google/apiclient-services:dev-master
我都试过了。得到了相同的结果。
===
我的问题是:
这些甚至是正确的 API 任务吗?
在哪里可以找到这些操作的 SDK 库? (或者,如果有人对如何在不使用 SDK 的情况下使用 PHP cURL 直接向 API 执行这些任务提出了建议)
我希望所有操作都发生在 PHP 中,但如果您有使用其他方法或语言或控制台命令行的有效解决方案,只要它可以由我的应用程序执行我可以使用它。
提前致谢!
在获得答案之前,请确保 Resource Manager API 已启用。这对于 REST 方法和程序化方法是必需的。
要修改给定项目中用户的 IAM 绑定,需要调用两个端点,这两个端点已记录在案 here。那些将是:
- 获取当前 IAM 配置:https://cloud.google.com/resource-manager/reference/rest/v1/projects/getIamPolicy
- 要设置新的 IAM 策略:https://cloud.google.com/resource-manager/reference/rest/v1/projects/setIamPolicy
在第 1 步和第 2 步之间,需要修改第一个端点返回的 json,或者添加具有您选择的角色的用户,或者从中删除用户条目。要查看 add/remove 用户所需的 json 结构是什么,我建议检查上面共享的 link 以及检查第一个命令返回的有效负载。
虽然直接调用 REST api 是您的一种选择,但您也可以使用 gcloud CLI 来执行此类操作。由于用户似乎将 added/removed 一个接一个地使用命令行,因此命令行将是一个简单的选择,而且它需要较少的设置。这两个操作的命令是:
/ To add user role
gcloud projects add-iam-policy-binding PROJECT_ID --member=user:somebody@example.com --role=roles/viewer
/ To remove user role
gcloud projects remove-iam-policy-binding PROJECT_ID --member=user:somebody@example.com --role=roles/viewer
第三种选择是以编程方式进行。虽然我想提供一个 PHP 示例,但我没有足够的语言经验,但下面是一个允许 add/remove 角色的 Python 脚本。它是从 Quickstart 引导而来的,只做了一些小的改动,从我 运行 的测试来看,它应该可以正常工作。
# TODO: Install required libraries
# pip3 install --upgrade google-api-python-client google-auth google-auth-httplib2
import os
from google.oauth2 import service_account
import googleapiclient.discovery
def get_policy(crm_service, project_id, version=3):
"""Gets IAM policy for a project."""
policy = (
crm_service.projects()
.getIamPolicy(
resource=project_id,
body={"options": {"requestedPolicyVersion": version}},
)
.execute()
)
print(policy)
return policy
def set_policy(crm_service, project_id, policy):
"""Sets IAM policy for a project."""
policy = (
crm_service.projects()
.setIamPolicy(resource=project_id, body={"policy": policy})
.execute()
)
return policy
def initialize_service():
"""
Initializes a Cloud Resource Manager service.
The Environemnt variable GOOGLE_APPLICATION_CREDENTIALS must point to the service account key.json file
"""
credentials = service_account.Credentials.from_service_account_file(
filename=os.environ["GOOGLE_APPLICATION_CREDENTIALS"],
scopes=["https://www.googleapis.com/auth/cloud-platform"],
)
crm_service = googleapiclient.discovery.build(
"cloudresourcemanager", "v1", credentials=credentials
)
return crm_service
def modify_policy_add_role(crm_service, project_id, role, member):
"""Adds a new role binding to a policy."""
policy = get_policy(crm_service, project_id)
binding = None
for b in policy["bindings"]:
if b["role"] == role:
binding = b
break
if binding is not None and member not in binding["members"]:
binding["members"].append(member)
else:
binding = {"role": role, "members": [member]}
policy["bindings"].append(binding)
policy = set_policy(crm_service, project_id, policy)
def modify_policy_remove_member(crm_service, project_id, role, member):
"""Removes a member from a role binding."""
policy = get_policy(crm_service, project_id)
# The try-except below handles the case where the role isn't in the IAM policy
try:
binding = next(b for b in policy["bindings"] if b["role"] == role)
except StopIteration:
print("The role is not included in the IAM policy. Can't remove user")
raise KeyError
if "members" in binding and member in binding["members"]:
binding["members"].remove(member)
set_policy(crm_service, project_id, policy)
if __name__ == '__main__':
# TODO: Replace with your project ID
project_id = "projectID"
# TODO: Replace with the ID of your member in the form 'user:member@example.com'.
member = "user:somebody@example.com"
# TODO: Replace the role with the role you want to grant/remove
role = "roles/logging.logWriter"
# Initializes the client.
crm_service = initialize_service()
# Call modify_policy_add_role or modify_policy_remove_member as required
modify_policy_add_role(crm_service, project_id, role, member)
modify_policy_remove_member(crm_service, project_id, role, member)
简要总结:我有一个 PHP 网络应用程序,它使用 Google 云 PHP 客户端 SDK 与 Dialogflow 集成。那没问题。我现在需要让我的用户直接访问 GCP Dialogflow 仪表板,这部分意味着他们需要能够 add/remove 从我的应用程序中向用户授予 Dialogflow 权限。 (出于显而易见的原因,我不想给他们完整的项目 IAM 权限和访问权限)。
显然,权限由单独的“Google APIs PHP 的客户端库”处理。
这似乎是用于列出现有项目用户策略的 API:https://cloud.google.com/resource-manager/reference/rest/v1/projects/listOrgPolicies
我认为这是 add/remove 用户部分的 API,但不是那么明显:https://cloud.google.com/resource-manager/reference/rest/v1/projects/setIamPolicy
===
问题:
但是,当我 运行 上面引用的 listOrgPolicies API 中提供的示例代码时,我得到这个错误:
PHP Fatal error: Uncaught Error: Class 'Google_Service_CloudResourceManager_ListOrgPoliciesRequest' not found
composer require google/apiclient-services
和 composer require google/apiclient-services:dev-master
我都试过了。得到了相同的结果。
===
我的问题是:
这些甚至是正确的 API 任务吗?
在哪里可以找到这些操作的 SDK 库? (或者,如果有人对如何在不使用 SDK 的情况下使用 PHP cURL 直接向 API 执行这些任务提出了建议)
我希望所有操作都发生在 PHP 中,但如果您有使用其他方法或语言或控制台命令行的有效解决方案,只要它可以由我的应用程序执行我可以使用它。
提前致谢!
在获得答案之前,请确保 Resource Manager API 已启用。这对于 REST 方法和程序化方法是必需的。
要修改给定项目中用户的 IAM 绑定,需要调用两个端点,这两个端点已记录在案 here。那些将是:
- 获取当前 IAM 配置:https://cloud.google.com/resource-manager/reference/rest/v1/projects/getIamPolicy
- 要设置新的 IAM 策略:https://cloud.google.com/resource-manager/reference/rest/v1/projects/setIamPolicy
在第 1 步和第 2 步之间,需要修改第一个端点返回的 json,或者添加具有您选择的角色的用户,或者从中删除用户条目。要查看 add/remove 用户所需的 json 结构是什么,我建议检查上面共享的 link 以及检查第一个命令返回的有效负载。
虽然直接调用 REST api 是您的一种选择,但您也可以使用 gcloud CLI 来执行此类操作。由于用户似乎将 added/removed 一个接一个地使用命令行,因此命令行将是一个简单的选择,而且它需要较少的设置。这两个操作的命令是:
/ To add user role
gcloud projects add-iam-policy-binding PROJECT_ID --member=user:somebody@example.com --role=roles/viewer
/ To remove user role
gcloud projects remove-iam-policy-binding PROJECT_ID --member=user:somebody@example.com --role=roles/viewer
第三种选择是以编程方式进行。虽然我想提供一个 PHP 示例,但我没有足够的语言经验,但下面是一个允许 add/remove 角色的 Python 脚本。它是从 Quickstart 引导而来的,只做了一些小的改动,从我 运行 的测试来看,它应该可以正常工作。
# TODO: Install required libraries
# pip3 install --upgrade google-api-python-client google-auth google-auth-httplib2
import os
from google.oauth2 import service_account
import googleapiclient.discovery
def get_policy(crm_service, project_id, version=3):
"""Gets IAM policy for a project."""
policy = (
crm_service.projects()
.getIamPolicy(
resource=project_id,
body={"options": {"requestedPolicyVersion": version}},
)
.execute()
)
print(policy)
return policy
def set_policy(crm_service, project_id, policy):
"""Sets IAM policy for a project."""
policy = (
crm_service.projects()
.setIamPolicy(resource=project_id, body={"policy": policy})
.execute()
)
return policy
def initialize_service():
"""
Initializes a Cloud Resource Manager service.
The Environemnt variable GOOGLE_APPLICATION_CREDENTIALS must point to the service account key.json file
"""
credentials = service_account.Credentials.from_service_account_file(
filename=os.environ["GOOGLE_APPLICATION_CREDENTIALS"],
scopes=["https://www.googleapis.com/auth/cloud-platform"],
)
crm_service = googleapiclient.discovery.build(
"cloudresourcemanager", "v1", credentials=credentials
)
return crm_service
def modify_policy_add_role(crm_service, project_id, role, member):
"""Adds a new role binding to a policy."""
policy = get_policy(crm_service, project_id)
binding = None
for b in policy["bindings"]:
if b["role"] == role:
binding = b
break
if binding is not None and member not in binding["members"]:
binding["members"].append(member)
else:
binding = {"role": role, "members": [member]}
policy["bindings"].append(binding)
policy = set_policy(crm_service, project_id, policy)
def modify_policy_remove_member(crm_service, project_id, role, member):
"""Removes a member from a role binding."""
policy = get_policy(crm_service, project_id)
# The try-except below handles the case where the role isn't in the IAM policy
try:
binding = next(b for b in policy["bindings"] if b["role"] == role)
except StopIteration:
print("The role is not included in the IAM policy. Can't remove user")
raise KeyError
if "members" in binding and member in binding["members"]:
binding["members"].remove(member)
set_policy(crm_service, project_id, policy)
if __name__ == '__main__':
# TODO: Replace with your project ID
project_id = "projectID"
# TODO: Replace with the ID of your member in the form 'user:member@example.com'.
member = "user:somebody@example.com"
# TODO: Replace the role with the role you want to grant/remove
role = "roles/logging.logWriter"
# Initializes the client.
crm_service = initialize_service()
# Call modify_policy_add_role or modify_policy_remove_member as required
modify_policy_add_role(crm_service, project_id, role, member)
modify_policy_remove_member(crm_service, project_id, role, member)