瞭解如何使用欄位遮罩選擇性更新資源。在 Google Cloud中更新資源時,您可能只想修改特定欄位,而不是取代整個資源。Rust 用戶端程式庫支援欄位遮罩,可讓您精確控管要更新資源的哪些欄位,同時保留其他欄位不變。
必要條件
本指南使用 Secret Manager API,但相關概念也適用於其他 Google Cloud 資源和服務。
繼續操作前,請按照「使用 Secret Manager 建立及存取密鑰」一文的說明,啟用及驗證 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 代表一組符號欄位路徑。欄位遮罩會指定更新作業修改的欄位子集,或擷取作業傳回的欄位子集。
在更新作業中,欄位遮罩會指定要更新目標資源的哪些欄位。API 只會變更遮罩中指定的欄位值,其他欄位則維持不變。如果您傳遞資源來描述更新的值,API 會忽略遮罩未涵蓋的所有欄位值。如果您未在更新時提供欄位遮罩,作業會套用至所有欄位。
如要將欄位重設為預設值,請在遮罩中加入該欄位,並在提供的資源中設定預設值。如要重設資源的所有欄位,請提供資源的預設執行個體,並設定遮罩中的所有欄位,或不提供遮罩。
更新資源的欄位
首先,請初始化 Secret Manager 用戶端並建立密鑰:
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 方法可讓您在密鑰上設定 etag,防止覆寫並行更新。
更新密鑰後,您已設定標籤和註解,現在可以將欄位遮罩傳遞至 set_update_mask,指定要更新的欄位路徑:
.set_update_mask(FieldMask::default().set_paths(["annotations", "labels"]))
更新作業的輸出內容會顯示欄位已更新:
labels: {"updated": "your-label"},
...
annotations: {"updated": "your-annotations"},
更新欄位:完整程式碼
這個程式碼範例會初始化及建立密鑰,然後套用欄位遮罩:
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(())
}