列出层次结构中的所有资源

Google Cloud 中的资源按层次结构进行组织,其中每个节点(即组织、文件夹、项目等)都具有对其父项的引用。您可以在执行扫描时使用该引用作为关键过滤词,以提高资源搜索的一致性。

您可以使用自定义角色向用户授予权限。这些角色基于最小权限原则运作,并且通常仅提供执行特定任务所需的最低权限。

此方案可有效隔离不同的用户群组。例如:

  • 大型公司里的不同部门,其中每个部门都不应该能够查看其他部门的资源。
  • 拥有特定项目权限、但没有其他资源权限的承包商。

但是,由于自定义角色所赋予的权限有限,此类角色可能会导致您层次结构中的许多资源在执行列表操作时被忽略。 当以具有某一自定义角色的用户身份执行搜索时,如果系统没有显示某些资源,那么您可能很难判断导致这种情况的原因。

为避免这种情况,本页面讨论了列出资源层次结构中由 Cloud Resource Manager API 管理的所有资源的最佳实践。您可以使用本指南来配置自定义审核检查,或基于 Cloud Resource Manager API 打造您自己的用户体验。

列出所有资源

当您扫描资源层次结构以列出所有资源时,您会需要获得高度一致的结果。如果扫描遗漏了某些资源或提供了过时的结果,您将很难判断究竟发生了什么问题。为了确保您始终能够获得最准确且最完整的结果,建议使用服务账号并按以下方式进行扫描:

  1. 向服务账号授予组织资源中组织、文件夹和项目的 listget 权限。
  2. 如果您要列出项目资源和文件夹资源,请在过滤条件字符串中指定父资源。
  3. 针对您要查找的每种资源以及文件夹等中间资源,使用此服务账号运行 projects.list() 方法。

示例:列出所有资源

以下伪代码演示了如何列出您组织中的所有资源节点:

organizations = organizations.search()
projects = emptyList()

parentsToList = queueOf(organizations)
while (parent = parentsToList.pop()) {
  // TODO: Iterate over paginated results as needed.
  // TODO: Handle PERMISSION_DENIED appropriately.
  projects.addAll(projects.list(parent.type, parent.id))
  parentsToList.addAll(folders.list(parent))
}

在构建自定义用户体验时,您可能还需要混合使用搜索结果并根据需要加载父资源(同时还需要捕获 PERMISSION_DENIED 异常)。

缩短 gcloud 项目列表上的延迟时间

如果 gcloud projects list 查询失败或太长,则返回的 Google Cloud 项目数量可能过大。如需解决此问题,请将 filterpage-size 标志应用于 gcloud projects list 命令。

如需详细了解可以添加到 gcloud projects list 命令的标志,请参阅 gcloud 项目列表

排除 Apps 脚本项目示例

查询失败或延迟时间的最常见原因是组织中具有大量 Apps 脚本项目。以下示例展示了如何从项目列表中移除 Apps 脚本项目,并限制每页返回的资源数量。

gcloud projects list --filter="NOT parent.id: 'APPS_SCRIPT_FOLDER_ID' "--page-size='30'

获取 Apps 脚本文件夹 ID

如要查找 Apps 脚本文件夹 ID,请按以下步骤操作。

  1. 在 Google Cloud 控制台的工具栏中,点击搜索资源、文档、产品等,然后输入 apps-script

    转到 Google Cloud 控制台

  2. 资源下,选择 apps-script 文件夹。

  3. 文件夹 ID 下复制文件夹 ID。

搜索资源

如果扫描的目标是搜索之前某个时间创建的资源,您可以执行速度更快且具有最终一致性(而非高度一致性)的扫描。请注意,这种搜索方法可能会导致搜索结果忽略某些资源,尤其是最近发生过更改的任何资源。 要搜索资源,请执行以下操作:

  1. 使用对您要搜索的资源具有 get 权限的服务账号。
  2. 使用此服务账号运行 projects.search() 方法。

对被忽略的资源进行问题排查

如果您开发的是扫描工具,我们建议您使用在组织级层授予的 listget 权限。这样可防止因用户权限不完整而导致的问题,从而避免某些资源在列表中被忽略。

如果您设计的是检查用户权限的自定义用户体验,则没有简单的解决方案。如果用户没有组织级层的权限,他们就需要对每项资源拥有特定权限才能使该资源得以显示。如果用户对层次结构中某处的资源缺少权限,则某些资源可能就不会显示。

如果用户对特定资源具有 list 权限,但没有 get 权限,则该资源在 Google Cloud 控制台中根本不会显示。不过,您可以通过使用 API 或 Google Cloud CLI 指定搜索资源的父级来返回该资源。在尝试扫描资源层次结构时,Google Cloud 控制台与其他方法之间的这种差异常常会导致混淆。

下图演示了一些常见的权限配置,以及这些配置如何影响运行搜索的用户可以看到的资源。

列出所有资源

在此示例中,所有必需的权限均在组织资源级层授予。因此,在执行列表或搜索操作时,整个层次结构都是可见的。

缺少组织权限

此示例中的用户拥有除 resourcemanager.organizations.get 以外的所有必需权限,但其权限是在文件夹级层被授予的。由于存在权限缺口,该用户可以完整查看相关层次结构部分的列表或搜索结果,但无法查看其余层次结构部分的情况。

仅具有项目 get 权限

此示例显示的是仅具有文件夹资源级层 resourcemanager.projects.get 权限的用户体验。 该用户可以查看层次结构中该文件夹下的项目,但只能通过搜索进行查看。如果使用列表功能,则系统不会返回任何结果。

仅具有文件夹 get 权限

此示例显示了与上述示例相同的问题,其中被授予权限的用户只能通过搜索查找其文件夹资源。如果使用列表功能,则系统不会返回任何结果。

拥有多种权限

此示例中的用户在其整个组织中拥有多种权限。 该用户可以列出组织级层的文件夹,因此,在搜索中指定父资源即可在整个层次结构中找到所需内容。 该用户可以列出一个文件夹的项目资源(但不能列出另一个文件夹的项目资源),并且对层次结构底层的一个项目拥有 resourcemanager.projects.get 权限。

因此,该用户无法返回位于此资源层次结构左侧的项目。他们只能使用指定父资源的搜索列出右侧的项目,且在 Google Cloud 控制台中查看项目时,仅显示一个项目。

无法发现的资源

在此示例中,用户可以通过指定整个层次结构中的相应父资源来获取组织资源并列出项目资源。但是,该用户无权列出或搜索任何中间文件夹。如果该用户恰好知道其父文件夹的 ID,就可以搜索其项目。该用户无法查看这些文件夹,因此如果不知道相应文件夹 ID,就无法找到该 ID。Google Cloud 控制台中会显示的唯一资源是组织。

在设计您的自定义用户体验时,请务必注意与上述类似的情况。您可以结合使用列表和搜索操作来呈现资源层次结构。您还应考虑如何告知用户他们缺少查看整个资源层次结构所需的权限。