本文档介绍了如何将组织、文件夹或项目的资产快照导出到 BigQuery 表,然后对目录运行数据分析。BigQuery 提供类似于 SQL 的体验,让用户可以分析数据,并生成有意义的分析洞见,而无需使用自定义脚本。
准备工作
在您将运行 Cloud Asset Inventory 命令的项目中启用 Cloud Asset Inventory API。
确保您的账号具有调用 Cloud Asset Inventory API 的正确角色。如需了解每种通话类型的具体权限,请参阅权限。
如果您还没有要导出到的 BigQuery 数据集,请创建一个 BigQuery 数据集。
限制
导出 BigQuery 表数据时,Cloud Asset Inventory 不支持所有字段。
频繁更改的素材资源字段(例如
numBytes
、numLongTermBytes
、numPhysicalBytes
和numRows
)可能会使用null
值导出。不支持导出到 BigQuery 聚簇表。
不支持使用自定义 Cloud Key Management Service (Cloud KMS) 密钥加密的 BigQuery 表。
除非您导出到分区表,否则不支持将导出输出附加到现有表。目标表必须为空,或必须覆盖目标表。如需覆盖目标表,请将
--output-bigquery-force
标志与 gcloud CLI 搭配使用,或将"force": true
与 REST API 搭配使用。导出到为每种资源类型创建单独的表格时,不支持 Google Kubernetes Engine (GKE) 资源类型(
container.googleapis.com/Cluster
和container.googleapis.com/NodePool
除外)。如果之前针对同一目标发起的请求发起时间不到 15 分钟且仍在运行,Cloud Asset Inventory 会拒绝导出请求。不过,如果导出操作耗时超过 15 分钟,系统会将其标记为已完成,并允许针对同一目标发出新的导出请求。
ACCESS_POLICY
内容类型只能在组织级别导出。如果要导出到的表已存在且正在导出中,系统会返回
400
错误。
用于导出的 BigQuery 架构
每个 BigQuery 表由描述列名、数据类型和其他信息的架构进行定义。为导出设置内容类型决定了表的架构:
资源或未指定:如果将内容类型设置为
RESOURCE
或未指定内容类型,并将per-asset-type
标志设置为false
或未使用该标志,则会创建具有以下架构的 BigQuery 表。资源架构
[ { "name": "name", "type": "STRING", "mode": "NULLABLE" }, { "name": "asset_type", "type": "STRING", "mode": "NULLABLE" }, { "name": "resource", "type": "RECORD", "mode": "NULLABLE", "fields": [ { "name": "version", "type": "STRING", "mode": "NULLABLE" }, { "name": "discovery_document_uri", "type": "STRING", "mode": "NULLABLE" }, { "name": "discovery_name", "type": "STRING", "mode": "NULLABLE" }, { "name": "resource_url", "type": "STRING", "mode": "NULLABLE" }, { "name": "parent", "type": "STRING", "mode": "NULLABLE" }, { "name": "data", "type": "STRING", "mode": "NULLABLE" }, { "name": "location", "type": "STRING", "mode": "NULLABLE" } ] }, { "name": "ancestors", "type": "STRING", "mode": "REPEATED" }, { "name": "update_time", "type": "TIMESTAMP", "mode": "NULLABLE" } ]
resource.data
列是表示为 JSON 字符串的资源元数据。如果您将内容类型设置为
RESOURCE
或未设置内容类型,并将per-asset-type
标志设置为true
,则会为每种资产类型创建单独的表。每个表格的架构将包含映射到该资产类型的Resource.data
字段中的嵌套字段的记录类型列,最多可为 BigQuery 支持的 15 个嵌套级别。如需查看示例表格,请参阅 Google Cloud 控制台中的 export-assets-examples。IAM 政策:如果在 REST API 中将内容类型设置为
IAM_POLICY
,或在 gcloud CLI 中将内容类型设置为iam-policy
,就会创建具有以下架构的 BigQuery 表。IAM 政策架构
[ { "name": "name", "mode": "NULLABLE", "type": "STRING" }, { "name": "asset_type", "mode": "NULLABLE", "type": "STRING" }, { "fields": [ { "name": "version", "mode": "NULLABLE", "type": "INTEGER" }, { "fields": [ { "name": "role", "mode": "NULLABLE", "type": "STRING" }, { "name": "members", "mode": "REPEATED", "type": "STRING" }, { "fields": [ { "name": "expression", "mode": "NULLABLE", "type": "STRING" }, { "name": "title", "mode": "NULLABLE", "type": "STRING" }, { "name": "description", "mode": "NULLABLE", "type": "STRING" }, { "name": "location", "mode": "NULLABLE", "type": "STRING" } ], "name": "condition", "mode": "NULLABLE", "type": "RECORD" } ], "name": "bindings", "mode": "REPEATED", "type": "RECORD" }, { "fields": [ { "name": "service", "mode": "NULLABLE", "type": "STRING" }, { "fields": [ { "name": "log_type", "mode": "NULLABLE", "type": "INTEGER" }, { "name": "exempted_members", "mode": "REPEATED", "type": "STRING" } ], "name": "audit_log_configs", "mode": "REPEATED", "type": "RECORD" } ], "name": "audit_configs", "mode": "REPEATED", "type": "RECORD" }, { "name": "etag", "mode": "NULLABLE", "type": "STRING" } ], "name": "iam_policy", "mode": "NULLABLE", "type": "RECORD" }, { "name": "ancestors", "mode": "REPEATED", "type": "STRING" }, { "name": "update_time", "mode": "NULLABLE", "type": "TIMESTAMP" } ]
组织政策:如果在 REST API 中将内容类型设置为
ORG_POLICY
,或在 gcloud CLI 中将内容类型设置为org-policy
,就会创建具有以下架构的 BigQuery 表。组织政策架构
[ { "name": "name", "mode": "NULLABLE", "type": "STRING" }, { "name": "asset_type", "mode": "NULLABLE", "type": "STRING" }, { "fields": [ { "name": "version", "mode": "NULLABLE", "type": "INTEGER" }, { "name": "constraint", "mode": "NULLABLE", "type": "STRING" }, { "name": "etag", "mode": "NULLABLE", "type": "STRING" }, { "name": "update_time", "mode": "NULLABLE", "type": "TIMESTAMP" }, { "fields": [ { "name": "allowed_values", "mode": "REPEATED", "type": "STRING" }, { "name": "denied_values", "mode": "REPEATED", "type": "STRING" }, { "name": "all_values", "mode": "NULLABLE", "type": "INTEGER" }, { "name": "suggested_value", "mode": "NULLABLE", "type": "STRING" }, { "name": "inherit_from_parent", "mode": "NULLABLE", "type": "BOOLEAN" } ], "name": "list_policy", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "enforced", "mode": "NULLABLE", "type": "BOOLEAN" } ], "name": "boolean_policy", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "_present", "mode": "NULLABLE", "type": "BOOLEAN" } ], "name": "restore_default", "mode": "NULLABLE", "type": "RECORD" } ], "name": "org_policy", "mode": "REPEATED", "type": "RECORD" }, { "name": "ancestors", "mode": "REPEATED", "type": "STRING" }, { "name": "update_time", "mode": "NULLABLE", "type": "TIMESTAMP" } ]
VPCSC 政策:如果在 REST API 中将内容类型设置为
ACCESS_POLICY
,或在 gcloud CLI 中将内容类型设置为access-policy
,就会创建具有以下架构的 BigQuery 表。VPCSC 政策架构
[ { "name": "name", "mode": "NULLABLE", "type": "STRING" }, { "name": "asset_type", "mode": "NULLABLE", "type": "STRING" }, { "fields": [ { "name": "name", "mode": "NULLABLE", "type": "STRING" }, { "name": "parent", "mode": "NULLABLE", "type": "STRING" }, { "name": "title", "mode": "NULLABLE", "type": "STRING" }, { "name": "scopes", "mode": "REPEATED", "type": "STRING" }, { "name": "etag", "mode": "NULLABLE", "type": "STRING" } ], "name": "access_policy", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "name", "mode": "NULLABLE", "type": "STRING" }, { "name": "title", "mode": "NULLABLE", "type": "STRING" }, { "name": "description", "mode": "NULLABLE", "type": "STRING" }, { "fields": [ { "fields": [ { "name": "ip_subnetworks", "mode": "REPEATED", "type": "STRING" }, { "fields": [ { "name": "require_screenlock", "mode": "NULLABLE", "type": "BOOLEAN" }, { "name": "allowed_encryption_statuses", "mode": "REPEATED", "type": "INTEGER" }, { "fields": [ { "name": "os_type", "mode": "NULLABLE", "type": "INTEGER" }, { "name": "minimum_version", "mode": "NULLABLE", "type": "STRING" }, { "name": "require_verified_chrome_os", "mode": "NULLABLE", "type": "BOOLEAN" } ], "name": "os_constraints", "mode": "REPEATED", "type": "RECORD" }, { "name": "allowed_device_management_levels", "mode": "REPEATED", "type": "INTEGER" }, { "name": "require_admin_approval", "mode": "NULLABLE", "type": "BOOLEAN" }, { "name": "require_corp_owned", "mode": "NULLABLE", "type": "BOOLEAN" } ], "name": "device_policy", "mode": "NULLABLE", "type": "RECORD" }, { "name": "required_access_levels", "mode": "REPEATED", "type": "STRING" }, { "name": "negate", "mode": "NULLABLE", "type": "BOOLEAN" }, { "name": "members", "mode": "REPEATED", "type": "STRING" }, { "name": "regions", "mode": "REPEATED", "type": "STRING" } ], "name": "conditions", "mode": "REPEATED", "type": "RECORD" }, { "name": "combining_function", "mode": "NULLABLE", "type": "INTEGER" } ], "name": "basic", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "fields": [ { "name": "expression", "mode": "NULLABLE", "type": "STRING" }, { "name": "title", "mode": "NULLABLE", "type": "STRING" }, { "name": "description", "mode": "NULLABLE", "type": "STRING" }, { "name": "location", "mode": "NULLABLE", "type": "STRING" } ], "name": "expr", "mode": "NULLABLE", "type": "RECORD" } ], "name": "custom", "mode": "NULLABLE", "type": "RECORD" } ], "name": "access_level", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "name", "mode": "NULLABLE", "type": "STRING" }, { "name": "title", "mode": "NULLABLE", "type": "STRING" }, { "name": "description", "mode": "NULLABLE", "type": "STRING" }, { "name": "perimeter_type", "mode": "NULLABLE", "type": "INTEGER" }, { "fields": [ { "name": "resources", "mode": "REPEATED", "type": "STRING" }, { "name": "access_levels", "mode": "REPEATED", "type": "STRING" }, { "name": "restricted_services", "mode": "REPEATED", "type": "STRING" }, { "fields": [ { "name": "enable_restriction", "mode": "NULLABLE", "type": "BOOLEAN" }, { "name": "allowed_services", "mode": "REPEATED", "type": "STRING" } ], "name": "vpc_accessible_services", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "fields": [ { "fields": [ { "name": "access_level", "mode": "NULLABLE", "type": "STRING" }, { "name": "resource", "mode": "NULLABLE", "type": "STRING" } ], "name": "sources", "mode": "REPEATED", "type": "RECORD" }, { "name": "identities", "mode": "REPEATED", "type": "STRING" }, { "name": "identity_type", "mode": "NULLABLE", "type": "INTEGER" } ], "name": "ingress_from", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "fields": [ { "name": "service_name", "mode": "NULLABLE", "type": "STRING" }, { "fields": [ { "name": "method", "mode": "NULLABLE", "type": "STRING" }, { "name": "permission", "mode": "NULLABLE", "type": "STRING" } ], "name": "method_selectors", "mode": "REPEATED", "type": "RECORD" } ], "name": "operations", "mode": "REPEATED", "type": "RECORD" }, { "name": "resources", "mode": "REPEATED", "type": "STRING" } ], "name": "ingress_to", "mode": "NULLABLE", "type": "RECORD" } ], "name": "ingress_policies", "mode": "REPEATED", "type": "RECORD" }, { "fields": [ { "fields": [ { "name": "identities", "mode": "REPEATED", "type": "STRING" }, { "name": "identity_type", "mode": "NULLABLE", "type": "INTEGER" } ], "name": "egress_from", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "resources", "mode": "REPEATED", "type": "STRING" }, { "fields": [ { "name": "service_name", "mode": "NULLABLE", "type": "STRING" }, { "fields": [ { "name": "method", "mode": "NULLABLE", "type": "STRING" }, { "name": "permission", "mode": "NULLABLE", "type": "STRING" } ], "name": "method_selectors", "mode": "REPEATED", "type": "RECORD" } ], "name": "operations", "mode": "REPEATED", "type": "RECORD" }, { "name": "external_resources", "mode": "REPEATED", "type": "STRING" } ], "name": "egress_to", "mode": "NULLABLE", "type": "RECORD" } ], "name": "egress_policies", "mode": "REPEATED", "type": "RECORD" } ], "name": "status", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "resources", "mode": "REPEATED", "type": "STRING" }, { "name": "access_levels", "mode": "REPEATED", "type": "STRING" }, { "name": "restricted_services", "mode": "REPEATED", "type": "STRING" }, { "fields": [ { "name": "enable_restriction", "mode": "NULLABLE", "type": "BOOLEAN" }, { "name": "allowed_services", "mode": "REPEATED", "type": "STRING" } ], "name": "vpc_accessible_services", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "fields": [ { "fields": [ { "name": "access_level", "mode": "NULLABLE", "type": "STRING" }, { "name": "resource", "mode": "NULLABLE", "type": "STRING" } ], "name": "sources", "mode": "REPEATED", "type": "RECORD" }, { "name": "identities", "mode": "REPEATED", "type": "STRING" }, { "name": "identity_type", "mode": "NULLABLE", "type": "INTEGER" } ], "name": "ingress_from", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "fields": [ { "name": "service_name", "mode": "NULLABLE", "type": "STRING" }, { "fields": [ { "name": "method", "mode": "NULLABLE", "type": "STRING" }, { "name": "permission", "mode": "NULLABLE", "type": "STRING" } ], "name": "method_selectors", "mode": "REPEATED", "type": "RECORD" } ], "name": "operations", "mode": "REPEATED", "type": "RECORD" }, { "name": "resources", "mode": "REPEATED", "type": "STRING" } ], "name": "ingress_to", "mode": "NULLABLE", "type": "RECORD" } ], "name": "ingress_policies", "mode": "REPEATED", "type": "RECORD" }, { "fields": [ { "fields": [ { "name": "identities", "mode": "REPEATED", "type": "STRING" }, { "name": "identity_type", "mode": "NULLABLE", "type": "INTEGER" } ], "name": "egress_from", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "resources", "mode": "REPEATED", "type": "STRING" }, { "fields": [ { "name": "service_name", "mode": "NULLABLE", "type": "STRING" }, { "fields": [ { "name": "method", "mode": "NULLABLE", "type": "STRING" }, { "name": "permission", "mode": "NULLABLE", "type": "STRING" } ], "name": "method_selectors", "mode": "REPEATED", "type": "RECORD" } ], "name": "operations", "mode": "REPEATED", "type": "RECORD" }, { "name": "external_resources", "mode": "REPEATED", "type": "STRING" } ], "name": "egress_to", "mode": "NULLABLE", "type": "RECORD" } ], "name": "egress_policies", "mode": "REPEATED", "type": "RECORD" } ], "name": "spec", "mode": "NULLABLE", "type": "RECORD" }, { "name": "use_explicit_dry_run_spec", "mode": "NULLABLE", "type": "BOOLEAN" } ], "name": "service_perimeter", "mode": "NULLABLE", "type": "RECORD" }, { "name": "ancestors", "mode": "REPEATED", "type": "STRING" }, { "name": "update_time", "mode": "NULLABLE", "type": "TIMESTAMP" } ]
OSConfig 实例清单:在 REST API 中将内容类型设置为
OS_INVENTORY
或 gcloud CLI 中的os-inventory
时,您需要创建一个 BigQuery 表格,该表格具有以下架构。操作系统清单架构
[ { "name": "name", "mode": "NULLABLE", "type": "STRING" }, { "name": "asset_type", "mode": "NULLABLE", "type": "STRING" }, { "fields": [ { "name": "name", "mode": "NULLABLE", "type": "STRING" }, { "fields": [ { "name": "hostname", "mode": "NULLABLE", "type": "STRING" }, { "name": "long_name", "mode": "NULLABLE", "type": "STRING" }, { "name": "short_name", "mode": "NULLABLE", "type": "STRING" }, { "name": "version", "mode": "NULLABLE", "type": "STRING" }, { "name": "architecture", "mode": "NULLABLE", "type": "STRING" }, { "name": "kernel_version", "mode": "NULLABLE", "type": "STRING" }, { "name": "kernel_release", "mode": "NULLABLE", "type": "STRING" }, { "name": "osconfig_agent_version", "mode": "NULLABLE", "type": "STRING" } ], "name": "os_info", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "key", "mode": "NULLABLE", "type": "STRING" }, { "fields": [ { "name": "id", "mode": "NULLABLE", "type": "STRING" }, { "name": "origin_type", "mode": "NULLABLE", "type": "INTEGER" }, { "name": "create_time", "mode": "NULLABLE", "type": "TIMESTAMP" }, { "name": "update_time", "mode": "NULLABLE", "type": "TIMESTAMP" }, { "name": "type", "mode": "NULLABLE", "type": "INTEGER" }, { "fields": [ { "fields": [ { "name": "package_name", "mode": "NULLABLE", "type": "STRING" }, { "name": "architecture", "mode": "NULLABLE", "type": "STRING" }, { "name": "version", "mode": "NULLABLE", "type": "STRING" } ], "name": "yum_package", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "package_name", "mode": "NULLABLE", "type": "STRING" }, { "name": "architecture", "mode": "NULLABLE", "type": "STRING" }, { "name": "version", "mode": "NULLABLE", "type": "STRING" } ], "name": "apt_package", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "package_name", "mode": "NULLABLE", "type": "STRING" }, { "name": "architecture", "mode": "NULLABLE", "type": "STRING" }, { "name": "version", "mode": "NULLABLE", "type": "STRING" } ], "name": "zypper_package", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "package_name", "mode": "NULLABLE", "type": "STRING" }, { "name": "architecture", "mode": "NULLABLE", "type": "STRING" }, { "name": "version", "mode": "NULLABLE", "type": "STRING" } ], "name": "googet_package", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "patch_name", "mode": "NULLABLE", "type": "STRING" }, { "name": "category", "mode": "NULLABLE", "type": "STRING" }, { "name": "severity", "mode": "NULLABLE", "type": "STRING" }, { "name": "summary", "mode": "NULLABLE", "type": "STRING" } ], "name": "zypper_patch", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "title", "mode": "NULLABLE", "type": "STRING" }, { "name": "description", "mode": "NULLABLE", "type": "STRING" }, { "fields": [ { "name": "id", "mode": "NULLABLE", "type": "STRING" }, { "name": "name", "mode": "NULLABLE", "type": "STRING" } ], "name": "categories", "mode": "REPEATED", "type": "RECORD" }, { "name": "kb_article_ids", "mode": "REPEATED", "type": "STRING" }, { "name": "support_url", "mode": "NULLABLE", "type": "STRING" }, { "name": "more_info_urls", "mode": "REPEATED", "type": "STRING" }, { "name": "update_id", "mode": "NULLABLE", "type": "STRING" }, { "name": "revision_number", "mode": "NULLABLE", "type": "INTEGER" }, { "name": "last_deployment_change_time", "mode": "NULLABLE", "type": "TIMESTAMP" } ], "name": "wua_package", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "caption", "mode": "NULLABLE", "type": "STRING" }, { "name": "description", "mode": "NULLABLE", "type": "STRING" }, { "name": "hot_fix_id", "mode": "NULLABLE", "type": "STRING" }, { "name": "install_time", "mode": "NULLABLE", "type": "TIMESTAMP" } ], "name": "qfe_package", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "package_name", "mode": "NULLABLE", "type": "STRING" }, { "name": "architecture", "mode": "NULLABLE", "type": "STRING" }, { "name": "version", "mode": "NULLABLE", "type": "STRING" } ], "name": "cos_package", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "display_name", "mode": "NULLABLE", "type": "STRING" }, { "name": "display_version", "mode": "NULLABLE", "type": "STRING" }, { "name": "publisher", "mode": "NULLABLE", "type": "STRING" }, { "fields": [ { "name": "year", "mode": "NULLABLE", "type": "INTEGER" }, { "name": "month", "mode": "NULLABLE", "type": "INTEGER" }, { "name": "day", "mode": "NULLABLE", "type": "INTEGER" } ], "name": "install_date", "mode": "NULLABLE", "type": "RECORD" }, { "name": "help_link", "mode": "NULLABLE", "type": "STRING" } ], "name": "windows_application", "mode": "NULLABLE", "type": "RECORD" } ], "name": "installed_package", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "fields": [ { "name": "package_name", "mode": "NULLABLE", "type": "STRING" }, { "name": "architecture", "mode": "NULLABLE", "type": "STRING" }, { "name": "version", "mode": "NULLABLE", "type": "STRING" } ], "name": "yum_package", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "package_name", "mode": "NULLABLE", "type": "STRING" }, { "name": "architecture", "mode": "NULLABLE", "type": "STRING" }, { "name": "version", "mode": "NULLABLE", "type": "STRING" } ], "name": "apt_package", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "package_name", "mode": "NULLABLE", "type": "STRING" }, { "name": "architecture", "mode": "NULLABLE", "type": "STRING" }, { "name": "version", "mode": "NULLABLE", "type": "STRING" } ], "name": "zypper_package", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "package_name", "mode": "NULLABLE", "type": "STRING" }, { "name": "architecture", "mode": "NULLABLE", "type": "STRING" }, { "name": "version", "mode": "NULLABLE", "type": "STRING" } ], "name": "googet_package", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "patch_name", "mode": "NULLABLE", "type": "STRING" }, { "name": "category", "mode": "NULLABLE", "type": "STRING" }, { "name": "severity", "mode": "NULLABLE", "type": "STRING" }, { "name": "summary", "mode": "NULLABLE", "type": "STRING" } ], "name": "zypper_patch", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "title", "mode": "NULLABLE", "type": "STRING" }, { "name": "description", "mode": "NULLABLE", "type": "STRING" }, { "fields": [ { "name": "id", "mode": "NULLABLE", "type": "STRING" }, { "name": "name", "mode": "NULLABLE", "type": "STRING" } ], "name": "categories", "mode": "REPEATED", "type": "RECORD" }, { "name": "kb_article_ids", "mode": "REPEATED", "type": "STRING" }, { "name": "support_url", "mode": "NULLABLE", "type": "STRING" }, { "name": "more_info_urls", "mode": "REPEATED", "type": "STRING" }, { "name": "update_id", "mode": "NULLABLE", "type": "STRING" }, { "name": "revision_number", "mode": "NULLABLE", "type": "INTEGER" }, { "name": "last_deployment_change_time", "mode": "NULLABLE", "type": "TIMESTAMP" } ], "name": "wua_package", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "caption", "mode": "NULLABLE", "type": "STRING" }, { "name": "description", "mode": "NULLABLE", "type": "STRING" }, { "name": "hot_fix_id", "mode": "NULLABLE", "type": "STRING" }, { "name": "install_time", "mode": "NULLABLE", "type": "TIMESTAMP" } ], "name": "qfe_package", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "package_name", "mode": "NULLABLE", "type": "STRING" }, { "name": "architecture", "mode": "NULLABLE", "type": "STRING" }, { "name": "version", "mode": "NULLABLE", "type": "STRING" } ], "name": "cos_package", "mode": "NULLABLE", "type": "RECORD" }, { "fields": [ { "name": "display_name", "mode": "NULLABLE", "type": "STRING" }, { "name": "display_version", "mode": "NULLABLE", "type": "STRING" }, { "name": "publisher", "mode": "NULLABLE", "type": "STRING" }, { "fields": [ { "name": "year", "mode": "NULLABLE", "type": "INTEGER" }, { "name": "month", "mode": "NULLABLE", "type": "INTEGER" }, { "name": "day", "mode": "NULLABLE", "type": "INTEGER" } ], "name": "install_date", "mode": "NULLABLE", "type": "RECORD" }, { "name": "help_link", "mode": "NULLABLE", "type": "STRING" } ], "name": "windows_application", "mode": "NULLABLE", "type": "RECORD" } ], "name": "available_package", "mode": "NULLABLE", "type": "RECORD" } ], "name": "value", "mode": "NULLABLE", "type": "RECORD" } ], "name": "items", "mode": "REPEATED", "type": "RECORD" }, { "name": "update_time", "mode": "NULLABLE", "type": "TIMESTAMP" } ], "name": "os_inventory", "mode": "NULLABLE", "type": "RECORD" }, { "name": "ancestors", "mode": "REPEATED", "type": "STRING" }, { "name": "update_time", "mode": "NULLABLE", "type": "TIMESTAMP" } ]
关系:如果在 REST API 中将内容类型设置为
RELATIONSHIP
,或在 gcloud CLI 中将内容类型设置为relationship
,就会创建具有以下架构的 BigQuery 表。关系架构
[ { "name": "name", "mode": "NULLABLE", "type": "STRING" }, { "name": "asset_type", "mode": "NULLABLE", "type": "STRING" }, { "fields": [ { "name": "asset", "mode": "NULLABLE", "type": "STRING" }, { "name": "asset_type", "mode": "NULLABLE", "type": "STRING" }, { "name": "ancestors", "mode": "REPEATED", "type": "STRING" }, { "name": "relationship_type", "mode": "NULLABLE", "type": "STRING" } ], "name": "related_asset", "mode": "NULLABLE", "type": "RECORD" }, { "name": "ancestors", "mode": "REPEATED", "type": "STRING" }, { "name": "update_time", "mode": "NULLABLE", "type": "TIMESTAMP" } ]
导出资产快照
gcloud
gcloud asset export \ --SCOPE \ --billing-project=BILLING_PROJECT_ID \ --asset-types=ASSET_TYPE_1,ASSET_TYPE_2,... \ --content-type=CONTENT_TYPE \ --relationship-types=RELATIONSHIP_TYPE_1,RELATIONSHIP_TYPE_2,... \ --snapshot-time="SNAPSHOT_TIME" \ --bigquery-table=projects/BIGQUERY_PROJECT_ID/datasets/DATASET_ID/tables/TABLE_NAME \ --output-bigquery-force
请提供以下值:
-
SCOPE
:请使用以下某个值:-
project=PROJECT_ID
,其中PROJECT_ID
是包含要导出的资产元数据的项目的 ID。 -
folder=FOLDER_ID
,其中FOLDER_ID
是包含要导出的资产元数据的文件夹的 ID。如何查找 Google Cloud 文件夹的 ID
Google Cloud 控制台
如需查找 Google Cloud 文件夹的 ID,请完成以下步骤:
-
转到 Google Cloud 控制台。
- 点击菜单栏中的切换器列表框。
- 从列表框中选择您的组织。
- 搜索您的文件夹名称。文件夹 ID 显示在文件夹名称旁边。
gcloud CLI
您可以使用以下命令检索位于组织级的文件夹的 ID: Google Cloud
gcloud resource-manager folders list \ --organization=$(gcloud organizations describe ORGANIZATION_NAME \ --format="value(name.segment(1))") \ --filter='"DISPLAY_NAME":"TOP_LEVEL_FOLDER_NAME"' \ --format="value(ID)"
其中 TOP_LEVEL_FOLDER_NAME 是文件夹名称的部分或完整字符串匹配。移除
--format
标志可查看有关找到的文件夹的更多信息。上一条命令不会返回文件夹内子文件夹的 ID。为此,请使用顶级文件夹的 ID 运行以下命令:
gcloud resource-manager folders list --folder=FOLDER_ID
-
-
organization=ORGANIZATION_ID
,其中ORGANIZATION_ID
是包含您要导出的资产元数据的组织的 ID。如何查找 Google Cloud 组织的 ID
Google Cloud 控制台
如需查找 Google Cloud 组织的 ID,请完成以下步骤:
-
转到 Google Cloud 控制台。
- 点击菜单栏中的切换器列表框。
- 从列表框中选择您的组织。
- 点击全部标签页。组织 ID 显示在组织名称旁边。
gcloud CLI
您可以使用以下命令检索组织的 ID: Google Cloud
gcloud organizations describe ORGANIZATION_NAME --format="value(name.segment(1))"
-
-
-
BILLING_PROJECT_ID
:可选。默认 Cloud Asset Inventory 服务代理所在的项目 ID,该代理具有管理您的 BigQuery 数据集和表的权限。 详细了解如何设置结算项目。 ASSET_TYPE_#
:可选。 可搜索的素材资源类型以英文逗号分隔的列表。 支持 与 RE2 兼容的正则表达式。如果正则表达式与任何支持的资源类型均不匹配,则会返回INVALID_ARGUMENT
错误。如果未指定--asset-types
,系统会返回所有资产类型。CONTENT_TYPE
:可选。您要检索的元数据的 内容类型。如果未指定--content-type
,则只会返回基本信息,例如素材资源名称、上次更新素材资源的时间,以及素材资源所属的项目、文件夹和组织。-
RELATIONSHIP_TYPE_#
:可选。需要有权访问 Security Command Center 高级或企业版,或 Gemini Cloud Assist。您要检索的资产关系类型的逗号分隔列表。您必须将CONTENT_TYPE
设置为RELATIONSHIP
,此功能才能正常运行。 -
SNAPSHOT_TIME
:可选。您希望截取资源快照的时间,采用 gcloud topic datetime 格式。该值不得超过过去 35 天。如果未指定--snapshot-time
,系统会截取当前时间的快照。 -
BIGQUERY_PROJECT_ID
:您要将 BigQuery 表导出到的项目的 ID。 -
DATASET_ID
:BigQuery 数据集的 ID。 -
TABLE_NAME
:要将元数据导出到的 BigQuery 表。如果该目录不存在,系统会创建一个。
--output-bigquery-force
标志会覆盖目标表(如果存在)。
如需了解所有选项,请参阅 gcloud CLI 参考文档。
示例
运行以下命令,将 my-project
项目中 2024 年 1 月 30 日的 resource
元数据导出到 BigQuery 表 my-table
。
gcloud asset export \ --project=my-project \ --content-type=resource \ --snapshot-time="2024-01-30" \ --bigquery-table=projects/my-project/datasets/my-dataset/tables/my-table \ --output-bigquery-force
示例响应
Export in progress for root asset [projects/my-project]. Use [gcloud asset operations describe projects/000000000000/operations/ExportAssets/RESOURCE/00000000000000000000000000000000] to check the status of the operation.
REST
HTTP 方法和网址:
POST https://cloudasset.googleapis.com/v1/SCOPE_PATH:exportAssets
标头:
X-Goog-User-Project: BILLING_PROJECT_ID
请求 JSON 正文:
{ "contentType": "CONTENT_TYPE", "relationshipTypes": [ "RELATIONSHIP_TYPE_1", "RELATIONSHIP_TYPE_2", "..." ], "readTime": "SNAPSHOT_TIME", "outputConfig": { "bigqueryDestination": { "dataset": "projects/BIGQUERY_PROJECT_ID/datasets/DATASET_ID", "table": "TABLE_NAME", "force": true } } }
请提供以下值:
-
SCOPE_PATH
:请使用以下某个值:允许使用的值包括:
-
projects/PROJECT_ID
,其中PROJECT_ID
是包含要导出的资产元数据的项目的 ID。 -
projects/PROJECT_NUMBER
,其中PROJECT_NUMBER
是包含要导出的资产元数据的项目的编号。如何查找 Google Cloud 项目编号
Google Cloud 控制台
如需查找 Google Cloud 项目编号,请完成以下步骤:
gcloud CLI
您可以使用以下命令检索 Google Cloud 项目编号:
gcloud projects describe PROJECT_ID --format="value(projectNumber)"
-
folders/FOLDER_ID
,其中FOLDER_ID
是包含要导出的资产元数据的文件夹的 ID。如何查找 Google Cloud 文件夹的 ID
Google Cloud 控制台
如需查找 Google Cloud 文件夹的 ID,请完成以下步骤:
-
转到 Google Cloud 控制台。
- 点击菜单栏中的切换器列表框。
- 从列表框中选择您的组织。
- 搜索您的文件夹名称。文件夹 ID 显示在文件夹名称旁边。
gcloud CLI
您可以使用以下命令检索位于组织级的文件夹的 ID: Google Cloud
gcloud resource-manager folders list \ --organization=$(gcloud organizations describe ORGANIZATION_NAME \ --format="value(name.segment(1))") \ --filter='"DISPLAY_NAME":"TOP_LEVEL_FOLDER_NAME"' \ --format="value(ID)"
其中 TOP_LEVEL_FOLDER_NAME 是文件夹名称的部分或完整字符串匹配。移除
--format
标志可查看有关找到的文件夹的更多信息。上一条命令不会返回文件夹内子文件夹的 ID。为此,请使用顶级文件夹的 ID 运行以下命令:
gcloud resource-manager folders list --folder=FOLDER_ID
-
-
organizations/ORGANIZATION_ID
,其中ORGANIZATION_ID
是包含您要导出的资产元数据的组织的 ID。如何查找 Google Cloud 组织的 ID
Google Cloud 控制台
如需查找 Google Cloud 组织的 ID,请完成以下步骤:
-
转到 Google Cloud 控制台。
- 点击菜单栏中的切换器列表框。
- 从列表框中选择您的组织。
- 点击全部标签页。组织 ID 显示在组织名称旁边。
gcloud CLI
您可以使用以下命令检索组织的 ID: Google Cloud
gcloud organizations describe ORGANIZATION_NAME --format="value(name.segment(1))"
-
-
-
BILLING_PROJECT_ID
:默认 Cloud Asset Inventory 服务代理所在的项目 ID,该代理有权管理您的 BigQuery 数据集和表。 详细了解如何设置结算项目。 CONTENT_TYPE
:您要检索的元数据的 内容类型。如果未指定contentType
,则只会返回基本信息,例如素材资源名称、上次更新素材资源的时间,以及素材资源所属的项目、文件夹和组织。-
RELATIONSHIP_TYPE_#
:可选。需要有权访问 Security Command Center 高级或企业版,或 Gemini Cloud Assist。您要检索的资产关系类型的逗号分隔列表。您必须将CONTENT_TYPE
设置为RELATIONSHIP
,此功能才能正常运行。 -
SNAPSHOT_TIME
:可选。您希望截取资源快照的时间,采用 RFC 3339 格式。该值不得超过过去 35 天。如果未指定readTime
,系统会在当前时间截取快照。 -
BIGQUERY_PROJECT_ID
:您要将 BigQuery 表导出到的项目的 ID。 -
DATASET_ID
:BigQuery 数据集的 ID。 -
TABLE_NAME
:要将元数据导出到的 BigQuery 表。如果该目录不存在,系统会创建一个。
"force": true
键值对会覆盖目标表(如果存在)。
如需了解所有选项,请参阅 REST 参考文档。
命令示例
运行以下命令之一,将 my-project
项目中 2024 年 1 月 30 日的 resource
元数据导出到 BigQuery 表 my-table
。
curl(Linux、macOS 或 Cloud Shell)
curl -X POST \ -H "X-Goog-User-Project: BILLING_PROJECT_ID" \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: application/json; charset=utf-8" \ -d '{ "contentType": "RESOURCE", "readTime": "2024-01-30T00:00:00Z", "outputConfig": { "bigqueryDestination": { "dataset": "projects/my-project/datasets/my-dataset", "table": "my-table", "force": true } } }' \ https://cloudasset.googleapis.com/v1/projects/my-project:exportAssets
PowerShell (Windows)
$cred = gcloud auth print-access-token $headers = @{ "X-Goog-User-Project" = "BILLING_PROJECT_ID"; "Authorization" = "Bearer $cred" } $body = @" { "contentType": "RESOURCE", "readTime": "2024-01-30T00:00:00Z", "outputConfig": { "bigqueryDestination": { "dataset": "projects/my-project/datasets/my-dataset", "table": "my-table", "force": true } } } "@ Invoke-WebRequest ` -Method POST ` -Headers $headers ` -ContentType: "application/json; charset=utf-8" ` -Body $body ` -Uri "https://cloudasset.googleapis.com/v1/projects/my-project:exportAssets" | Select-Object -Expand Content
示例响应
{ "name": "projects/000000000000/operations/ExportAssets/RESOURCE/00000000000000000000000000000000", "metadata": { "@type": "type.googleapis.com/google.cloud.asset.v1.ExportAssetsRequest", "parent": "projects/000000000000", "readTime": "2024-01-30T00:00:00Z", "contentType": "RESOURCE", "outputConfig": { "bigqueryDestination": { "dataset": "projects/my-project/datasets/my-dataset", "table": "my-table", "force": true } } } }
Go
如需了解如何安装和使用 Cloud Asset Inventory 客户端库,请参阅 Cloud Asset Inventory 客户端库。
如需向 Cloud Asset Inventory 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Java
如需了解如何安装和使用 Cloud Asset Inventory 客户端库,请参阅 Cloud Asset Inventory 客户端库。
如需向 Cloud Asset Inventory 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Node.js
如需了解如何安装和使用 Cloud Asset Inventory 客户端库,请参阅 Cloud Asset Inventory 客户端库。
如需向 Cloud Asset Inventory 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
Python
如需了解如何安装和使用 Cloud Asset Inventory 客户端库,请参阅 Cloud Asset Inventory 客户端库。
如需向 Cloud Asset Inventory 进行身份验证,请设置应用默认凭据。 如需了解详情,请参阅为本地开发环境设置身份验证。
将资产快照导出到按资产类型分隔的表
您可以使用 gcloud CLI 中的 --per-asset-type
标志和 REST API 请求中的 "separateTablesPerAssetType": true
,将资产导出到每个资产类型的单独 BigQuery 表。
在此模式下,每个表的名称都是 TABLE_NAME
与 _
(下划线)和资产类型名称串联而成。非字母数字字符将被替换为 _
。
如果导出到任何表失败,整个导出操作将会失败并返回第一个错误。之前成功导出的结果会保留。
以下类型会打包到 JSON 字符串中,以克服 Proto3 和 BigQuery 类型之间的兼容性问题。
google.protobuf.Timestamp
google.protobuf.Duration
google.protobuf.FieldMask
google.protobuf.ListValue
google.protobuf.Value
google.protobuf.Struct
google.api.*
gcloud
gcloud asset export \ --SCOPE \ --billing-project=BILLING_PROJECT_ID \ --asset-types=ASSET_TYPE_1,ASSET_TYPE_2,... \ --content-type=CONTENT_TYPE \ --relationship-types=RELATIONSHIP_TYPE_1,RELATIONSHIP_TYPE_2,... \ --snapshot-time="SNAPSHOT_TIME" \ --bigquery-table=projects/BIGQUERY_PROJECT_ID/datasets/DATASET_ID/tables/TABLE_NAME \ --per-asset-type \ --output-bigquery-force
请提供以下值:
-
SCOPE
:请使用以下某个值:-
project=PROJECT_ID
,其中PROJECT_ID
是包含要导出的资产元数据的项目的 ID。 -
folder=FOLDER_ID
,其中FOLDER_ID
是包含要导出的资产元数据的文件夹的 ID。如何查找 Google Cloud 文件夹的 ID
Google Cloud 控制台
如需查找 Google Cloud 文件夹的 ID,请完成以下步骤:
-
转到 Google Cloud 控制台。
- 点击菜单栏中的切换器列表框。
- 从列表框中选择您的组织。
- 搜索您的文件夹名称。文件夹 ID 显示在文件夹名称旁边。
gcloud CLI
您可以使用以下命令检索位于组织级的文件夹的 ID: Google Cloud
gcloud resource-manager folders list \ --organization=$(gcloud organizations describe ORGANIZATION_NAME \ --format="value(name.segment(1))") \ --filter='"DISPLAY_NAME":"TOP_LEVEL_FOLDER_NAME"' \ --format="value(ID)"
其中 TOP_LEVEL_FOLDER_NAME 是文件夹名称的部分或完整字符串匹配。移除
--format
标志可查看有关找到的文件夹的更多信息。上一条命令不会返回文件夹内子文件夹的 ID。为此,请使用顶级文件夹的 ID 运行以下命令:
gcloud resource-manager folders list --folder=FOLDER_ID
-
-
organization=ORGANIZATION_ID
,其中ORGANIZATION_ID
是包含您要导出的资产元数据的组织的 ID。如何查找 Google Cloud 组织的 ID
Google Cloud 控制台
如需查找 Google Cloud 组织的 ID,请完成以下步骤:
-
转到 Google Cloud 控制台。
- 点击菜单栏中的切换器列表框。
- 从列表框中选择您的组织。
- 点击全部标签页。组织 ID 显示在组织名称旁边。
gcloud CLI
您可以使用以下命令检索组织的 ID: Google Cloud
gcloud organizations describe ORGANIZATION_NAME --format="value(name.segment(1))"
-
-
-
BILLING_PROJECT_ID
:可选。默认 Cloud Asset Inventory 服务代理所在的项目 ID,该代理具有管理您的 BigQuery 数据集和表的权限。 详细了解如何设置结算项目。 ASSET_TYPE_#
:可选。 可搜索的素材资源类型以英文逗号分隔的列表。 支持 与 RE2 兼容的正则表达式。如果正则表达式与任何支持的资源类型均不匹配,则会返回INVALID_ARGUMENT
错误。如果未指定--asset-types
,系统会返回所有资产类型。CONTENT_TYPE
:可选。您要检索的元数据的 内容类型。如果未指定--content-type
,则只会返回基本信息,例如素材资源名称、上次更新素材资源的时间,以及素材资源所属的项目、文件夹和组织。-
RELATIONSHIP_TYPE_#
:可选。需要有权访问 Security Command Center 高级或企业版,或 Gemini Cloud Assist。您要检索的资产关系类型的逗号分隔列表。您必须将CONTENT_TYPE
设置为RELATIONSHIP
,此功能才能正常运行。 -
SNAPSHOT_TIME
:可选。您希望截取资源快照的时间,采用 gcloud topic datetime 格式。该值不得超过过去 35 天。如果未指定--snapshot-time
,系统会截取当前时间的快照。 -
BIGQUERY_PROJECT_ID
:您要将 BigQuery 表导出到的项目的 ID。 -
DATASET_ID
:BigQuery 数据集的 ID。 -
TABLE_NAME
:要将元数据导出到的 BigQuery 表。如果该目录不存在,系统会创建一个。
--output-bigquery-force
标志会覆盖目标表(如果存在)。
如需了解所有选项,请参阅 gcloud CLI 参考文档。
示例
运行以下命令,将 my-project
项目中 2024 年 1 月 30 日的 resource
元数据导出到多个以 my-table
为前缀的 BigQuery 表。
gcloud asset export \ --project=my-project \ --content-type=resource \ --snapshot-time="2024-01-30" \ --bigquery-table=projects/my-project/datasets/my-dataset/tables/my-table \ --per-asset-type \ --output-bigquery-force
REST
HTTP 方法和网址:
POST https://cloudasset.googleapis.com/v1/SCOPE_PATH:exportAssets
标头:
X-Goog-User-Project: BILLING_PROJECT_ID
请求 JSON 正文:
{ "contentType": "CONTENT_TYPE", "relationshipTypes": [ "RELATIONSHIP_TYPE_1", "RELATIONSHIP_TYPE_2", "..." ], "readTime": "SNAPSHOT_TIME", "outputConfig": { "bigqueryDestination": { "dataset": "projects/BIGQUERY_PROJECT_ID/datasets/DATASET_ID", "table": "TABLE_NAME", "force": true, "separateTablesPerAssetType": true } } }
请提供以下值:
-
SCOPE_PATH
:请使用以下某个值:允许使用的值包括:
-
projects/PROJECT_ID
,其中PROJECT_ID
是包含要导出的资产元数据的项目的 ID。 -
projects/PROJECT_NUMBER
,其中PROJECT_NUMBER
是包含要导出的资产元数据的项目的编号。如何查找 Google Cloud 项目编号
Google Cloud 控制台
如需查找 Google Cloud 项目编号,请完成以下步骤:
gcloud CLI
您可以使用以下命令检索 Google Cloud 项目编号:
gcloud projects describe PROJECT_ID --format="value(projectNumber)"
-
folders/FOLDER_ID
,其中FOLDER_ID
是包含要导出的资产元数据的文件夹的 ID。如何查找 Google Cloud 文件夹的 ID
Google Cloud 控制台
如需查找 Google Cloud 文件夹的 ID,请完成以下步骤:
-
转到 Google Cloud 控制台。
- 点击菜单栏中的切换器列表框。
- 从列表框中选择您的组织。
- 搜索您的文件夹名称。文件夹 ID 显示在文件夹名称旁边。
gcloud CLI
您可以使用以下命令检索位于组织级的文件夹的 ID: Google Cloud
gcloud resource-manager folders list \ --organization=$(gcloud organizations describe ORGANIZATION_NAME \ --format="value(name.segment(1))") \ --filter='"DISPLAY_NAME":"TOP_LEVEL_FOLDER_NAME"' \ --format="value(ID)"
其中 TOP_LEVEL_FOLDER_NAME 是文件夹名称的部分或完整字符串匹配。移除
--format
标志可查看有关找到的文件夹的更多信息。上一条命令不会返回文件夹内子文件夹的 ID。为此,请使用顶级文件夹的 ID 运行以下命令:
gcloud resource-manager folders list --folder=FOLDER_ID
-
-
organizations/ORGANIZATION_ID
,其中ORGANIZATION_ID
是包含您要导出的资产元数据的组织的 ID。如何查找 Google Cloud 组织的 ID
Google Cloud 控制台
如需查找 Google Cloud 组织的 ID,请完成以下步骤:
-
转到 Google Cloud 控制台。
- 点击菜单栏中的切换器列表框。
- 从列表框中选择您的组织。
- 点击全部标签页。组织 ID 显示在组织名称旁边。
gcloud CLI
您可以使用以下命令检索组织的 ID: Google Cloud
gcloud organizations describe ORGANIZATION_NAME --format="value(name.segment(1))"
-
-
-
BILLING_PROJECT_ID
:默认 Cloud Asset Inventory 服务代理所在的项目 ID,该代理有权管理您的 BigQuery 数据集和表。 详细了解如何设置结算项目。 CONTENT_TYPE
:您要检索的元数据的 内容类型。如果未指定contentType
,则只会返回基本信息,例如素材资源名称、上次更新素材资源的时间,以及素材资源所属的项目、文件夹和组织。-
RELATIONSHIP_TYPE_#
:可选。需要有权访问 Security Command Center 高级或企业版,或 Gemini Cloud Assist。您要检索的资产关系类型的逗号分隔列表。您必须将CONTENT_TYPE
设置为RELATIONSHIP
,此功能才能正常运行。 -
SNAPSHOT_TIME
:可选。您希望截取资源快照的时间,采用 RFC 3339 格式。该值不得超过过去 35 天。如果未指定readTime
,系统会在当前时间截取快照。 -
BIGQUERY_PROJECT_ID
:您要将 BigQuery 表导出到的项目的 ID。 -
DATASET_ID
:BigQuery 数据集的 ID。 -
TABLE_NAME
:要将元数据导出到的 BigQuery 表。如果该目录不存在,系统会创建一个。
"force": true
键值对会覆盖目标表(如果存在)。
命令示例
运行以下命令之一,将 my-project
项目中 2024 年 1 月 30 日的 resource
元数据导出到多个以 my-table
为前缀的 BigQuery 表。
curl(Linux、macOS 或 Cloud Shell)
curl -X POST \ -H "X-Goog-User-Project: BILLING_PROJECT_ID" \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: application/json; charset=utf-8" \ -d '{ "contentType": "RESOURCE", "readTime": "2024-01-30T00:00:00Z", "outputConfig": { "bigqueryDestination": { "dataset": "projects/my-project/datasets/my-dataset", "table": "my-table", "force": true, "separateTablesPerAssetType": true } } }' \ https://cloudasset.googleapis.com/v1/projects/my-project:exportAssets
PowerShell (Windows)
$cred = gcloud auth print-access-token $headers = @{ "X-Goog-User-Project" = "BILLING_PROJECT_ID"; "Authorization" = "Bearer $cred" } $body = @" { "contentType": "RESOURCE", "readTime": "2024-01-30T00:00:00Z", "outputConfig": { "bigqueryDestination": { "dataset": "projects/my-project/datasets/my-dataset", "table": "my-table", "force": true, "separateTablesPerAssetType": true } } } "@ Invoke-WebRequest ` -Method POST ` -Headers $headers ` -ContentType: "application/json; charset=utf-8" ` -Body $body ` -Uri "https://cloudasset.googleapis.com/v1/projects/my-project:exportAssets" | Select-Object -Expand Content
将资产快照导出到时间单位列分区表
您可以将项目中的资产导出到时间单位列分区表。导出的快照存储在名为 TABLE_NAME
的 BigQuery 表中,该表具有每天粒度和两个额外的时间戳列 readTime
和 requestTime
,其中一个列由您指定为包含 PARTITION_KEY
值的分区列。
如需将项目中的资产导出到分区表,请发出以下任一请求。
gcloud
gcloud asset export \ --SCOPE \ --billing-project=BILLING_PROJECT_ID \ --asset-types=ASSET_TYPE_1,ASSET_TYPE_2,... \ --content-type=CONTENT_TYPE \ --relationship-types=RELATIONSHIP_TYPE_1,RELATIONSHIP_TYPE_2,... \ --snapshot-time="SNAPSHOT_TIME" \ --bigquery-table=projects/BIGQUERY_PROJECT_ID/datasets/DATASET_ID/tables/TABLE_NAME \ --partition-key=PARTITION_KEY \ --output-bigquery-force
请提供以下值:
-
SCOPE
:请使用以下某个值:-
project=PROJECT_ID
,其中PROJECT_ID
是包含要导出的资产元数据的项目的 ID。 -
folder=FOLDER_ID
,其中FOLDER_ID
是包含要导出的资产元数据的文件夹的 ID。如何查找 Google Cloud 文件夹的 ID
Google Cloud 控制台
如需查找 Google Cloud 文件夹的 ID,请完成以下步骤:
-
转到 Google Cloud 控制台。
- 点击菜单栏中的切换器列表框。
- 从列表框中选择您的组织。
- 搜索您的文件夹名称。文件夹 ID 显示在文件夹名称旁边。
gcloud CLI
您可以使用以下命令检索位于组织级的文件夹的 ID: Google Cloud
gcloud resource-manager folders list \ --organization=$(gcloud organizations describe ORGANIZATION_NAME \ --format="value(name.segment(1))") \ --filter='"DISPLAY_NAME":"TOP_LEVEL_FOLDER_NAME"' \ --format="value(ID)"
其中 TOP_LEVEL_FOLDER_NAME 是文件夹名称的部分或完整字符串匹配。移除
--format
标志可查看有关找到的文件夹的更多信息。上一条命令不会返回文件夹内子文件夹的 ID。为此,请使用顶级文件夹的 ID 运行以下命令:
gcloud resource-manager folders list --folder=FOLDER_ID
-
-
organization=ORGANIZATION_ID
,其中ORGANIZATION_ID
是包含您要导出的资产元数据的组织的 ID。如何查找 Google Cloud 组织的 ID
Google Cloud 控制台
如需查找 Google Cloud 组织的 ID,请完成以下步骤:
-
转到 Google Cloud 控制台。
- 点击菜单栏中的切换器列表框。
- 从列表框中选择您的组织。
- 点击全部标签页。组织 ID 显示在组织名称旁边。
gcloud CLI
您可以使用以下命令检索组织的 ID: Google Cloud
gcloud organizations describe ORGANIZATION_NAME --format="value(name.segment(1))"
-
-
-
BILLING_PROJECT_ID
:可选。默认 Cloud Asset Inventory 服务代理所在的项目 ID,该代理具有管理您的 BigQuery 数据集和表的权限。 详细了解如何设置结算项目。 ASSET_TYPE_#
:可选。 可搜索的素材资源类型以英文逗号分隔的列表。 支持 与 RE2 兼容的正则表达式。如果正则表达式与任何支持的资源类型均不匹配,则会返回INVALID_ARGUMENT
错误。如果未指定--asset-types
,系统会返回所有资产类型。CONTENT_TYPE
:可选。您要检索的元数据的 内容类型。如果未指定--content-type
,则只会返回基本信息,例如素材资源名称、上次更新素材资源的时间,以及素材资源所属的项目、文件夹和组织。-
RELATIONSHIP_TYPE_#
:可选。需要有权访问 Security Command Center 高级或企业版,或 Gemini Cloud Assist。您要检索的资产关系类型的逗号分隔列表。您必须将CONTENT_TYPE
设置为RELATIONSHIP
,此功能才能正常运行。 -
SNAPSHOT_TIME
:可选。您希望截取资源快照的时间,采用 gcloud topic datetime 格式。该值不得超过过去 35 天。如果未指定--snapshot-time
,系统会截取当前时间的快照。 -
BIGQUERY_PROJECT_ID
:您要将 BigQuery 表导出到的项目的 ID。 -
DATASET_ID
:BigQuery 数据集的 ID。 -
TABLE_NAME
:要将元数据导出到的 BigQuery 表。如果该目录不存在,系统会创建一个。 -
PARTITION_KEY
:导出到 BigQuery 分区表时的 分区键列。有效值为read-time
和request-time
。
--output-bigquery-force
标志会覆盖目标表中相应分区中的数据。不同分区中的数据保持不变。
如果未指定 --output-bigquery-force
,则导出的数据会附加到相应分区。
如果架构更新或附加数据的尝试失败,导出操作将失败。这包括目标表已存在且不具有导出操作预期的架构的情况。
如需了解所有选项,请参阅 gcloud CLI 参考文档。
示例
运行以下命令,将 my-project
项目中 2024 年 1 月 30 日的 resource
元数据导出到 BigQuery 表 my-table
。
gcloud asset export \ --project=projects/my-project \ --content-type=resource \ --snapshot-time="2024-01-30" \ --bigquery-table=projects/my-project/datasets/my-dataset/tables/my-table \ --partition-key=my-partition-key \ --output-bigquery-force
REST
HTTP 方法和网址:
POST https://cloudasset.googleapis.com/v1/SCOPE_PATH:exportAssets
标头:
X-Goog-User-Project: BILLING_PROJECT_ID
请求 JSON 正文:
{ "contentType": "CONTENT_TYPE", "relationshipTypes": [ "RELATIONSHIP_TYPE_1", "RELATIONSHIP_TYPE_2", "..." ], "readTime": "SNAPSHOT_TIME", "outputConfig": { "bigqueryDestination": { "dataset": "projects/BIGQUERY_PROJECT_ID/datasets/DATASET_ID", "table": "TABLE_NAME", "partitionSpec": { "partitionKey": "PARTITION_KEY" }, "force": true, } } }
请提供以下值:
-
SCOPE_PATH
:请使用以下某个值:允许使用的值包括:
-
projects/PROJECT_ID
,其中PROJECT_ID
是包含要导出的资产元数据的项目的 ID。 -
projects/PROJECT_NUMBER
,其中PROJECT_NUMBER
是包含要导出的资产元数据的项目的编号。如何查找 Google Cloud 项目编号
Google Cloud 控制台
如需查找 Google Cloud 项目编号,请完成以下步骤:
gcloud CLI
您可以使用以下命令检索 Google Cloud 项目编号:
gcloud projects describe PROJECT_ID --format="value(projectNumber)"
-
folders/FOLDER_ID
,其中FOLDER_ID
是包含要导出的资产元数据的文件夹的 ID。如何查找 Google Cloud 文件夹的 ID
Google Cloud 控制台
如需查找 Google Cloud 文件夹的 ID,请完成以下步骤:
-
转到 Google Cloud 控制台。
- 点击菜单栏中的切换器列表框。
- 从列表框中选择您的组织。
- 搜索您的文件夹名称。文件夹 ID 显示在文件夹名称旁边。
gcloud CLI
您可以使用以下命令检索位于组织级的文件夹的 ID: Google Cloud
gcloud resource-manager folders list \ --organization=$(gcloud organizations describe ORGANIZATION_NAME \ --format="value(name.segment(1))") \ --filter='"DISPLAY_NAME":"TOP_LEVEL_FOLDER_NAME"' \ --format="value(ID)"
其中 TOP_LEVEL_FOLDER_NAME 是文件夹名称的部分或完整字符串匹配。移除
--format
标志可查看有关找到的文件夹的更多信息。上一条命令不会返回文件夹内子文件夹的 ID。为此,请使用顶级文件夹的 ID 运行以下命令:
gcloud resource-manager folders list --folder=FOLDER_ID
-
-
organizations/ORGANIZATION_ID
,其中ORGANIZATION_ID
是包含您要导出的资产元数据的组织的 ID。如何查找 Google Cloud 组织的 ID
Google Cloud 控制台
如需查找 Google Cloud 组织的 ID,请完成以下步骤:
-
转到 Google Cloud 控制台。
- 点击菜单栏中的切换器列表框。
- 从列表框中选择您的组织。
- 点击全部标签页。组织 ID 显示在组织名称旁边。
gcloud CLI
您可以使用以下命令检索组织的 ID: Google Cloud
gcloud organizations describe ORGANIZATION_NAME --format="value(name.segment(1))"
-
-
-
BILLING_PROJECT_ID
:默认 Cloud Asset Inventory 服务代理所在的项目 ID,该代理有权管理您的 BigQuery 数据集和表。 详细了解如何设置结算项目。 CONTENT_TYPE
:您要检索的元数据的 内容类型。如果未指定contentType
,则只会返回基本信息,例如素材资源名称、上次更新素材资源的时间,以及素材资源所属的项目、文件夹和组织。-
RELATIONSHIP_TYPE_#
:可选。需要有权访问 Security Command Center 高级或企业版,或 Gemini Cloud Assist。您要检索的资产关系类型的逗号分隔列表。您必须将CONTENT_TYPE
设置为RELATIONSHIP
,此功能才能正常运行。 -
SNAPSHOT_TIME
:可选。您希望截取资源快照的时间,采用 RFC 3339 格式。该值不得超过过去 35 天。如果未指定readTime
,系统会在当前时间截取快照。 -
BIGQUERY_PROJECT_ID
:您要将 BigQuery 表导出到的项目的 ID。 -
DATASET_ID
:BigQuery 数据集的 ID。 -
TABLE_NAME
:要将元数据导出到的 BigQuery 表。如果该目录不存在,系统会创建一个。 -
PARTITION_KEY
:导出到 BigQuery 分区表时的 分区键列。有效值为READ_TIME
和REQUEST_TIME
。
"force": true
键值对会覆盖目标表中相应分区中的数据。不同分区中的数据保持不变。
如果 force
未设置或设置为 false
,则导出的数据会附加到相应的分区。
如果架构更新或附加数据的尝试失败,导出操作将失败。这包括目标表已存在且不具有导出操作预期的架构的情况。
命令示例
运行以下命令之一,将 my-project
项目中 2024 年 1 月 30 日的 resource
元数据导出到 BigQuery 表 my-table
。
curl(Linux、macOS 或 Cloud Shell)
curl -X POST \ -H "X-Goog-User-Project: BILLING_PROJECT_ID" \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: application/json; charset=utf-8" \ -d '{ "contentType": "RESOURCE", "readTime": "2024-01-30T00:00:00Z", "outputConfig": { "bigqueryDestination": { "dataset": "projects/my-project/datasets/my-dataset", "table": "my-table", "partitionSpec": { "partitionKey": "my-partition-key" }, "force": true, } } }' \ https://cloudasset.googleapis.com/v1/projects/my-project:exportAssets
PowerShell (Windows)
$cred = gcloud auth print-access-token $headers = @{ "X-Goog-User-Project" = "BILLING_PROJECT_ID"; "Authorization" = "Bearer $cred" } $body = @" { "contentType": "RESOURCE", "readTime": "2024-01-30T00:00:00Z", "outputConfig": { "bigqueryDestination": { "dataset": "projects/my-project/datasets/my-dataset", "table": "my-table", "partitionSpec": { "partitionKey": "my-partition-key" }, "force": true, } } } "@ Invoke-WebRequest ` -Method POST ` -Headers $headers ` -ContentType: "application/json; charset=utf-8" ` -Body $body ` -Uri "https://cloudasset.googleapis.com/v1/projects/my-project:exportAssets" | Select-Object -Expand Content
查看导出作业的状态
导出需要一些时间才能完成。如需检查导出操作是否已完成,您可以使用操作 ID 查询该操作。
请注意,即使导出操作已完成,其他用户也可能会针对同一目标位置发出另一个导出请求(作为其他操作)。在先前请求完成后,或者 15 分钟后,您可以向同一目标发出新的导出请求。在这些条件之外发出的导出请求将被 Cloud Asset Inventory 拒绝。
gcloud
如需查看导出状态,请按照以下说明操作:
从导出请求的响应中获取包含操作 ID 的
OPERATION_PATH
。OPERATION_PATH
显示在导出响应中,其格式如下所示:projects/PROJECT_NUMBER/operations/ExportAssets/CONTENT_TYPE/OPERATION_ID
要检查导出状态,请使用
OPERATION_PATH
运行以下命令:gcloud asset operations describe OPERATION_PATH
REST
如需查看导出状态,请按照以下说明操作:
从导出请求的响应中获取包含操作 ID 的
OPERATION_PATH
。OPERATION_PATH
显示为导出响应中name
字段的值,其格式如下所示:projects/PROJECT_NUMBER/operations/ExportAssets/CONTENT_TYPE/OPERATION_ID
如需检查导出状态,请发出以下请求。
REST
HTTP 方法和网址:
GET https://cloudasset.googleapis.com/v1/OPERATION_PATH
命令示例
curl(Linux、macOS 或 Cloud Shell)
curl -X GET \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ https://cloudasset.googleapis.com/v1/OPERATION_PATH
PowerShell (Windows)
$cred = gcloud auth print-access-token $headers = @{ "Authorization" = "Bearer $cred" } Invoke-WebRequest ` -Method GET ` -Headers $headers ` -Uri "https://cloudasset.googleapis.com/v1/OPERATION_PATH" | Select-Object -Expand Content
在 BigQuery 中查看资产快照
控制台
在 Google Cloud 控制台中,前往 BigQuery Studio 页面。
如需显示数据集中的表和视图,请打开导航面板。在资源部分,选择项目以将其展开,然后选择数据集。
从列表中选择您的表。
选择详情并记下行数中的值。使用 gcloud CLI 或 REST API 时,您可能需要此值来控制结果的起点。
要查看一组数据示例,请选择预览。
REST
如需浏览表的数据,请调用 tabledata.list
。在 tableId
参数中,指定表的名称。
您可以配置以下可选参数来控制输出。
maxResults
是要返回的结果数上限。selectedFields
是要返回的列的逗号分隔列表;如果未指定此参数,则会返回所有列。startIndex
是要读取的起始行的索引(从零开始)。
返回的值会封装在一个 JSON 对象中,您必须对此对象进行解析,具体请参阅 tabledata.list
参考文档。
在 BigQuery 中查询资产快照
将快照导出到 BigQuery 后,您便可以对资产元数据运行查询。
默认情况下,BigQuery 运行交互式(也称为按需)查询作业,也就是说,查询会尽快执行。交互式查询计入并发速率限制和每日限制。
查询结果会保存到临时表或永久表中。您可以选择在现有表中附加或覆盖数据,或者创建新表(如果不存在同名的表)。
如需运行将输出写入临时表的交互式查询,请完成以下步骤。
控制台
在 Google Cloud 控制台中,前往 BigQuery Studio 页面。
选择
编写新查询。在查询编辑器文本区域中,输入有效的 BigQuery SQL 查询。
可选:如需更改数据处理位置,请完成以下步骤。
选择更多,然后选择查询设置。
在处理位置下,选择自动选择,然后选择数据的位置。
要更新查询设置,请选择保存。
选择运行。
REST
要启动新作业,请调用
jobs.insert
方法。在作业资源中,设置以下参数。在
configuration
字段中,将query
字段设置为描述 BigQuery 查询作业的 JobConfigurationQuery。在
jobReference
字段中,为您的作业适当设置location
字段。
要轮询结果,请调用
getQueryResults
。直到jobComplete
等于true
。您可以在errors
列表中检查错误和警告。
其他 SQL 查询示例
本部分提供了在将资产元数据导出到 BigQuery 后对其进行分析的示例 SQL 查询。如需了解详情,请参阅标准 SQL 查询语法。
直接查询可用列
要查找每种资产类型的数量,请运行以下查询:
SELECT asset_type, COUNT(*) AS asset_count
FROM `PROJECT_ID.DATASET_ID.TABLE_NAME`
GROUP BY asset_type
ORDER BY asset_count DESC
使用重复字段
如需查找向 Gmail 账号授予访问权限的 Identity and Access Management (IAM) 政策,请运行以下查询。BigQuery 使用 UNNEST
将重复字段展平为可以直接查询的表:
SELECT name, asset_type, bindings.role
FROM `PROJECT_ID.DATASET_ID.TABLE_NAME`
JOIN UNNEST(iam_policy.bindings) AS bindings
JOIN UNNEST(bindings.members) AS principals
WHERE principals like "%@gmail.com"
如需查找允许使用公共 IP 地址创建的组织、文件夹或项目,请运行以下查询。此查询很有用,因为除非配置了 SSL 或代理,否则允许使用 Cloud SQL 实例的公共 IP 地址可能会引入漏洞:
SELECT name
FROM `PROJECT_ID.DATASET_ID.TABLE_NAME`
JOIN UNNEST(org_policy) AS op
WHERE
op.constraint = "constraints/sql.restrictPublicIp"
AND (op.boolean_policy IS NULL OR op.boolean_policy.enforced = FALSE);
如需在项目的同一 VPC Service Controls 服务边界内查找组织、文件夹或项目,请运行以下查询:
SELECT service_perimeter.title, service_perimeter.status.resources
FROM `PROJECT_ID.DATASET_ID.TABLE_NAME`
CROSS JOIN UNNEST(service_perimeter.status.resources) as resource
WHERE resource = "projects/PROJECT_ID";
使用 JSON 字符串
如需查找打开的防火墙规则,请运行以下查询。详细了解 BigQuery 中使用的 JSON 函数。
CREATE TEMP FUNCTION json2array(json STRING)
RETURNS ARRAY<STRING>
LANGUAGE js AS """
return JSON.parse(json).map(x=>JSON.stringify(x));
""";
SELECT firewall.name, firewall.resource.parent, JSON_EXTRACT(firewall.resource.data, '$.sourceRanges') AS sourceRanges
FROM `PROJECT_ID.DATASET_ID.TABLE_NAME` AS firewall
JOIN UNNEST(json2array(JSON_EXTRACT(firewall.resource.data, '$.sourceRanges'))) AS source_ranges
WHERE asset_type="compute.googleapis.com/Firewall" AND JSON_EXTRACT(firewall.resource.data, '$.sourceRanges') IS NOT NULL AND JSON_EXTRACT_SCALAR(source_ranges, '$') = "0.0.0.0/0"
通过按资源类型导出到不同的表,您可以更轻松、更快速地查找打开的防火墙规则。
SELECT firewall.name, firewall.resource.parent, sourceRanges
FROM `PROJECT_ID.DATASET_ID.STRUCTURED_INSTANCE_TABLE_NAME` AS firewall
JOIN UNNEST(firewall.resource.data.sourceRanges) AS sourceRanges
WHERE sourceRanges = "0.0.0.0/0";
联接不同资源类型的表
要联接不同资源类型的表,请运行以下查询。以下示例显示了如何查找未挂接任何虚拟机的所有子网。首先,查询会查找所有子网。然后,查询会从该列表中选择其 selfLink
值不存在的子网。
CREATE TEMP FUNCTION json2array(json STRING)
RETURNS ARRAY<STRING>
LANGUAGE js AS """
return JSON.parse(json).map(x=>JSON.stringify(x));
""";
SELECT name, JSON_EXTRACT(subnetwork.resource.data, '$.selfLink') AS selflink
FROM `PROJECT_ID.DATASET_ID.TABLE_NAME` AS subnetwork
WHERE asset_type = "compute.googleapis.com/Subnetwork" AND (JSON_EXTRACT(subnetwork.resource.data, '$.selfLink') NOT IN
(SELECT DISTINCT JSON_EXTRACT(network_interfaces, '$.subnetwork')
FROM `PROJECT_ID.DATASET_ID.TABLE_NAME` as instance
JOIN UNNEST(json2array(JSON_EXTRACT(instance.resource.data, '$.networkInterfaces'))) AS network_interfaces
WHERE asset_type ="compute.googleapis.com/Instance"
AND JSON_EXTRACT(instance.resource.data, '$.networkInterfaces') IS NOT NULL
)) IS NULL
通过按资源类型导出到不同的表,您可以使用更简单、速度更快的查询来查找没有挂接任何虚拟机的所有子网。
SELECT name, subnetwork.resource.data.selfLink
FROM `PROJECT_ID.DATASET_ID.STRUCTURED_SUBNETWORK_TABLE_NAME` AS subnetwork
WHERE
(
subnetwork.resource.data.selfLink
NOT IN (
SELECT DISTINCT networkInterface.subnetwork
FROM `PROJECT_ID.DATASET_ID.STRUCTURED_INSTANCE_TABLE_NAME` as instance
JOIN
UNNEST(instance.resource.data.networkInterfaces) AS networkInterface
WHERE
networkInterface IS NOT NULL
)
) IS NULL;
查找存在 CVE-2021-44228 漏洞的 Dataproc 集群
CREATE TEMP FUNCTION vulnerable_version(imageVersion STRING)
RETURNS BOOL
LANGUAGE js AS r"""
const version_regexp = /(?<major>\d+)(?:\.)(?<minor>\d+)(?:\.)?(?<sub>\d+)?/g;
let match = version_regexp.exec(imageVersion);
if(match.groups.major < 1){
return true;
}
if (match.groups.major == 1){
if (match.groups.minor < 3){
return true;
}
if(match.groups.minor == 3 && match.groups.sub < 95){
return true;
}
if(match.groups.minor == 4 && match.groups.sub < 77){
return true;
}
if(match.groups.minor == 5 && match.groups.sub < 53){
return true;
}
}
if (match.groups.major == 2 && match.groups.minor == 0 && match.groups.sub < 27){
return true;
}
return false;
""";
SELECT
c.name,
c.resource.data.projectId AS project_id,
c.resource.data.clusterName AS cluster_name,
c.resource.data.config.softwareConfig.imageVersion AS image_version,
c.resource.data.status.state AS cluster_state,
vulnerable_version(c.resource.data.config.softwareConfig.imageVersion) AS is_vulnerable
FROM
`PROJECT_ID.DATASET_ID.TABLE_NAME_PREFIX_dataproc_googleapis_com_Cluster` c
INNER JOIN `PROJECT_ID.DATASET_ID.TABLE_NAME_PREFIX_cloudresourcemanager_googleapis_com_Project` p
ON p.resource.data.projectId = c.resource.data.projectId
WHERE
c.resource.data.config.softwareConfig.imageVersion IS NOT NULL
AND c.resource.data.status.state = "RUNNING"
AND p.resource.data.lifecycleState = "ACTIVE";