Secret Manager 支持使用实体标记 (ETag) 实现乐观并发控制。
在某些情况下,并行更新同一资源的两个进程可能会相互干扰,其中后一个进程会覆盖前一个进程的工作量。
ETag 提供了一种允许乐观并发控制的方法,即允许进程在对资源执行操作之前查看资源是否已修改。
将 ETag 与 Secret Manager 结合使用
以下资源修改请求支持 ETag:
在 secrets.patch 请求中,请求 ETag 嵌入在密文数据中。其他所有请求均接受可选 etag
参数。
如果提供 ETag 且与当前资源 ETag 匹配,则请求成功;否则,请求将失败并显示 FAILED_PRECONDITION
错误和 HTTP 状态代码 400。如果未提供 ETag,则请求将继续而不检查当前存储的 ETag 值。
资源 ETag 在创建资源时生成(projects.secrets.create、projects.secrets.addVersion),并针对上面列出的每个修改请求进行更新。修改请求仅更新它适用的资源的 ETag。也就是说,更新 Secret 版本不会影响 Secret ETag,反之亦然。
即使更新不会更改资源的状态,它仍会更新资源 ETag。
请思考以下示例:
-
用户 1 尝试启用某个密文版本,但不知道该版本已启用。系统会处理此请求,但只会更改版本的 ETag,不会更改任何其他内容。
-
用户 2 使用旧版 ETag 尝试停用该版本。
-
之所以会失败,是因为系统会识别较新的 ETag,这表示有更新的 intent 用于保持该版本处于启用状态。
由于 ETag 的更改,即使是看似不重要的更新也非常重要。这样可以确保数据一致性,尤其是在多个用户或系统与同一资源交互时。
每当包含资源(Secret 或 SecretVersion)时,响应中都会返回资源 etag
。
使用 ETag 删除 Secret
本部分介绍了如何在删除密文时使用 ETag。如果密文被其他进程修改,则删除操作将失败。
gcloud
在使用下面的命令数据之前,请先进行以下替换:
- SECRET_ID:密钥的 ID 或密钥的完全限定标识符。
- LOCATION:密钥的 Google Cloud 位置。
- ETAG:Secret 的实体标记。ETag 必须包含括起的英文引号。
例如,如果 ETag 值为
"abc"
,则 shell 转义值将为"\"abc\""
。
执行以下命令:
Linux、macOS 或 Cloud Shell
gcloud secrets delete SECRET_ID --location=LOCATION \ --etag "ETAG"
Windows (PowerShell)
gcloud secrets delete SECRET_ID --location=LOCATION ` --etag "ETAG"
Windows (cmd.exe)
gcloud secrets delete SECRET_ID --location=LOCATION ^ --etag "ETAG"
REST
在使用任何请求数据之前,请先进行以下替换:
- LOCATION:密钥的 Google Cloud 位置。
- PROJECT_ID:Google Cloud 项目 ID。
- SECRET_ID:密钥的 ID 或密钥的完全限定标识符。
- ETAG:Secret 的实体标记。ETag 被指定为网址查询字符串的一部分,并且必须采用网址编码。例如,如果 ETag 值为
"abc"
,则网址编码值将为%22abc%22
,因为英文引号字符编码为%22
。
HTTP 方法和网址:
DELETE https://secretmanager.LOCATION.rep.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/secrets/SECRET_ID?etag=ETAG
请求 JSON 正文:
{}
如需发送请求,请选择以下方式之一:
curl
将请求正文保存在名为 request.json
的文件中,然后执行以下命令:
curl -X DELETE \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://secretmanager.LOCATION.rep.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/secrets/SECRET_ID?etag=ETAG"
PowerShell
将请求正文保存在名为 request.json
的文件中,然后执行以下命令:
$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }
Invoke-WebRequest `
-Method DELETE `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://secretmanager.LOCATION.rep.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/secrets/SECRET_ID?etag=ETAG" | Select-Object -Expand Content
您应该收到类似以下内容的 JSON 响应:
{}
Go
如需运行此代码,请先设置 Go 开发环境并安装 Secret Manager Go SDK。 在 Compute Engine 或 GKE 上,您必须使用 cloud-platform 范围进行身份验证。
Java
如需运行此代码,请先设置 Java 开发环境并安装 Secret Manager Java SDK。 在 Compute Engine 或 GKE 上,您必须使用 cloud-platform 范围进行身份验证。
Python
如需运行此代码,请先设置 Python 开发环境并安装 Secret Manager Python SDK。在 Compute Engine 或 GKE 上,您必须使用 cloud-platform 范围进行身份验证。
使用 ETag 更新 Secret
本部分介绍了如何在更新密文时使用 ETag。如果密文被其他进程修改,则更新操作将失败。
gcloud
在使用下面的命令数据之前,请先进行以下替换:
- SECRET_ID:密钥的 ID 或密钥的完全限定标识符。
- LOCATION:密钥的 Google Cloud 位置。
- KEY:标签名称。
- VALUE:相应的标签值。
- ETAG:Secret 的实体标记。ETag 必须包含括起的英文引号。
例如,如果 ETag 值为
"abc"
,则 shell 转义值将为"\"abc\""
。
执行以下命令:
Linux、macOS 或 Cloud Shell
gcloud secrets update SECRET_ID --location=LOCATION \ --update-labels "KEY=VALUE" \ --etag "ETAG"
Windows (PowerShell)
gcloud secrets update SECRET_ID --location=LOCATION ` --update-labels "KEY=VALUE" ` --etag "ETAG"
Windows (cmd.exe)
gcloud secrets update SECRET_ID --location=LOCATION ^ --update-labels "KEY=VALUE" ^ --etag "ETAG"
响应会返回 Secret。
REST
在使用任何请求数据之前,请先进行以下替换:
- LOCATION:密钥的 Google Cloud 位置。
- PROJECT_ID:Google Cloud 项目 ID。
- SECRET_ID:密钥的 ID 或密钥的完全限定标识符。
- ETAG:Secret 的实体标记。ETag 被指定为 Secret 上的一个字段,并且必须包含括起的英文引号。例如,如果 ETag 值为
"abc"
,则 JSON 转义值将为{"etag":"\"abc\""}
。 - KEY:标签名称。
- VALUE:相应的标签值。
HTTP 方法和网址:
PATCH https://secretmanager.LOCATION.rep.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/secrets/SECRET_ID?updateMask=labels
请求 JSON 正文:
{"etag":"ETAG", "labels":{"KEY": "VALUE"}}
如需发送请求,请选择以下方式之一:
curl
将请求正文保存在名为 request.json
的文件中,然后执行以下命令:
curl -X PATCH \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://secretmanager.LOCATION.rep.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/secrets/SECRET_ID?updateMask=labels"
PowerShell
将请求正文保存在名为 request.json
的文件中,然后执行以下命令:
$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }
Invoke-WebRequest `
-Method PATCH `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://secretmanager.LOCATION.rep.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/secrets/SECRET_ID?updateMask=labels" | Select-Object -Expand Content
您应该收到类似以下内容的 JSON 响应:
{ "name": "projects/PROJECT_ID/locations/LOCATION/secrets/SECRET_ID", "createTime": "2024-09-04T04:06:00.660420Z", "labels": { "KEY": "VALUE" }, "etag": "\"162145a4f894d5\"" }
Go
如需运行此代码,请先设置 Go 开发环境并安装 Secret Manager Go SDK。在 Compute Engine 或 GKE 上,您必须使用 cloud-platform 范围进行身份验证。
Java
如需运行此代码,请先设置 Java 开发环境并安装 Secret Manager Java SDK。 在 Compute Engine 或 GKE 上,您必须使用 cloud-platform 范围进行身份验证。
Python
如需运行此代码,请先设置 Python 开发环境并安装 Secret Manager Python SDK。在 Compute Engine 或 GKE 上,您必须使用 cloud-platform 范围进行身份验证。
使用 ETag 更新 Secret 版本
本部分介绍了如何在更新密文版本时使用 ETag。如果密文版本被其他进程修改,则更新操作将失败。
gcloud
在使用下面的命令数据之前,请先进行以下替换:
- VERSION_ID:密文版本的 ID。
- SECRET_ID:密钥的 ID 或密钥的完全限定标识符。
- LOCATION:密钥的 Google Cloud 位置。
- ETAG:实体标记。ETag 必须包含括起的英文引号。
例如,如果 ETag 值为
"abc"
,则 shell 转义值将为"\"abc\""
。
执行以下命令:
Linux、macOS 或 Cloud Shell
gcloud secrets versions disable VERSION_ID \ --secret SECRET_ID \ --location=LOCATION \ --etag "ETAG"
Windows (PowerShell)
gcloud secrets versions disable VERSION_ID ` --secret SECRET_ID ` --location=LOCATION ` --etag "ETAG"
Windows (cmd.exe)
gcloud secrets versions disable VERSION_ID ^ --secret SECRET_ID ^ --location=LOCATION ^ --etag "ETAG"
响应会返回 Secret。
REST
在使用任何请求数据之前,请先进行以下替换:
- LOCATION:密钥的 Google Cloud 位置
- PROJECT_ID:Google Cloud 项目 ID
- SECRET_ID:Secret 的 ID 或 Secret 的完全限定标识符
- VERSION_ID:Secret 版本的 ID
- ETAG:密文版本的实体标记。ETag 被指定为 SecretVersion 上的一个字段,并且必须包含括起的英文引号。例如,如果 ETag 值为
"abc"
,则 JSON 转义值将为{"etag":"\"abc\""}
。
HTTP 方法和网址:
POST https://secretmanager.LOCATION.rep.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/secrets/SECRET_ID/versions/VERSION_ID:disable
请求 JSON 正文:
{"etag":"ETAG"}
如需发送请求,请选择以下方式之一:
curl
将请求正文保存在名为 request.json
的文件中,然后执行以下命令:
curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json; charset=utf-8" \
-d @request.json \
"https://secretmanager.LOCATION.rep.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/secrets/SECRET_ID/versions/VERSION_ID:disable"
PowerShell
将请求正文保存在名为 request.json
的文件中,然后执行以下命令:
$cred = gcloud auth print-access-token
$headers = @{ "Authorization" = "Bearer $cred" }
Invoke-WebRequest `
-Method POST `
-Headers $headers `
-ContentType: "application/json; charset=utf-8" `
-InFile request.json `
-Uri "https://secretmanager.LOCATION.rep.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/secrets/SECRET_ID/versions/VERSION_ID:disable" | Select-Object -Expand Content
您应该收到类似以下内容的 JSON 响应:
{ "name": "projects/PROJECT_ID/locations/LOCATION/secrets/SECRET_ID/versions/VERSION_ID", "createTime": "2024-09-04T06:41:57.859674Z", "state": "DISABLED", "etag": "\"1621457b3c1459\"" }
Go
如需运行此代码,请先设置 Go 开发环境并安装 Secret Manager Go SDK。在 Compute Engine 或 GKE 上,您必须使用 cloud-platform 范围进行身份验证。
Java
如需运行此代码,请先设置 Java 开发环境并安装 Secret Manager Java SDK。 在 Compute Engine 或 GKE 上,您必须使用 cloud-platform 范围进行身份验证。
Python
如需运行此代码,请先设置 Python 开发环境并安装 Secret Manager Python SDK。在 Compute Engine 或 GKE 上,您必须使用 cloud-platform 范围进行身份验证。
此处的代码示例介绍了如何使用 ETag 启用密文版本。您还可以在其他密文变更操作期间指定 ETag,例如在停用或销毁密文版本时。请参阅 Secret Manager 的代码示例。