了解如何使用字段掩码选择性地更新资源。在 Google Cloud中更新 资源时,您可能只想修改特定字段,而不是替换整个 资源。Rust 客户端库支持字段掩码,让您可以精确控制要更新的资源字段,同时保持其他字段不变。
前提条件
本指南使用 Secret Manager API,但这些概念适用于 其他 Google Cloud 资源和服务。
在继续之前,请按照 使用 Secret Manager 创建和访问 Secret 中的说明启用 Secret Manager API 并进行身份验证。
如需获取有关 Rust 库的完整设置说明,请参阅 设置开发环境。
依赖项
启用 Secret Manager 后,在 Cargo.toml 文件中声明依赖项:
cargo add google-cloud-secretmanager-v1
cargo add tokio
安装已知类型
google_cloud_wkt crate 包含 Google Cloud API 的已知类型。
这些类型通常具有自定义 JSON 编码,并且可能会提供与常用 Rust 类型之间的转换函数。google_cloud_wkt crate 包含字段掩码类型 FieldMask。
将该 crate 添加为依赖项:
cargo add google-cloud-wkt
字段掩码
FieldMask 表示一组符号字段路径。字段掩码指定更新操作修改或 get 操作返回的字段子集。
在更新操作中,字段掩码指定要更新的目标资源的哪些字段。API 仅更改掩码中指定的字段的值,而不会触及其他字段。如果您传递资源来描述更新后的值,API 会忽略掩码未涵盖的所有字段的值。如果您在更新时未提供字段掩码,则该操作将应用于所有字段。
如需将字段重置为默认值,请在掩码中添加该字段,并在提供的资源中设置默认值。如需重置资源的所有字段,请提供资源的默认实例并在掩码中设置所有字段,或者不提供掩码。
更新资源中的字段
首先,初始化 Secret Manager 客户端并创建 Secret:
let client = SecretManagerService::builder().build().await?;
let secret = client
.create_secret()
.set_parent(format!("projects/{project_id}"))
.set_secret_id("your-secret")
.set_secret(
Secret::new().set_replication(Replication::new().set_automatic(Automatic::new())),
)
.send()
.await?;
println!("CREATE = {secret:?}");
创建操作的输出显示 labels 和 annotations 字段均为空。
以下代码会更新 labels 和 annotations 字段:
let tag = |mut labels: HashMap<_, _>, msg: &str| {
labels.insert("updated".to_string(), msg.to_string());
labels
};
let update = client
.update_secret()
.set_secret(
Secret::new()
.set_name(&secret.name)
.set_etag(secret.etag)
.set_labels(tag(secret.labels, "your-label"))
.set_annotations(tag(secret.annotations, "your-annotations")),
)
.set_update_mask(FieldMask::default().set_paths(["annotations", "labels"]))
.send()
.await?;
println!("UPDATE = {update:?}");
您可以使用 set_etag 方法在 Secret 上设置 etag,以防止覆盖并发更新。
在更新后的 Secret 上设置标签和注释后,您可以将字段掩码传递给 set_update_mask,以指定要更新的字段路径:
.set_update_mask(FieldMask::default().set_paths(["annotations", "labels"]))
更新操作的输出显示字段已更新:
labels: {"updated": "your-label"},
...
annotations: {"updated": "your-annotations"},
更新字段:完整代码
此示例代码会初始化并创建 Secret,然后应用字段掩码:
use google_cloud_secretmanager_v1::client::SecretManagerService;
use google_cloud_secretmanager_v1::model::replication::Automatic;
use google_cloud_secretmanager_v1::model::{Replication, Secret};
use google_cloud_wkt::FieldMask;
use std::collections::HashMap;
pub async fn sample(project_id: &str) -> anyhow::Result<()> {
let client = SecretManagerService::builder().build().await?;
let secret = client
.create_secret()
.set_parent(format!("projects/{project_id}"))
.set_secret_id("your-secret")
.set_secret(
Secret::new().set_replication(Replication::new().set_automatic(Automatic::new())),
)
.send()
.await?;
println!("CREATE = {secret:?}");
let tag = |mut labels: HashMap<_, _>, msg: &str| {
labels.insert("updated".to_string(), msg.to_string());
labels
};
let update = client
.update_secret()
.set_secret(
Secret::new()
.set_name(&secret.name)
.set_etag(secret.etag)
.set_labels(tag(secret.labels, "your-label"))
.set_annotations(tag(secret.annotations, "your-annotations")),
)
.set_update_mask(FieldMask::default().set_paths(["annotations", "labels"]))
.send()
.await?;
println!("UPDATE = {update:?}");
Ok(())
}