フィールド マスクを使用してリソースを選択的に更新する方法を説明します。 でリソースを更新する場合、リソース全体を置き換えるのではなく、特定のフィールドのみを変更したいことがあります。 Google CloudRust クライアント ライブラリはフィールド マスクをサポートしているため、リソースのどのフィールドを更新し、どのフィールドを変更しないかを正確に制御できます。
前提条件
このガイドでは 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 クレートには、 Google Cloud API の既知のタイプが含まれています。
これらのタイプには通常、カスタム JSON エンコードがあり、一般的に使用される Rust タイプとの間で変換を行う関数が用意されています。google_cloud_wkt クレートには、フィールド マスクタイプ FieldMask が含まれています。
クレートを依存関係として追加します。
cargo add google-cloud-wkt
フィールド マスク
FieldMask は、一連のシンボリック フィールド パスを表します。フィールド マスクは、更新オペレーションで変更されるフィールドまたは get オペレーションで返されるフィールドのサブセットを指定します。
更新オペレーションでは、フィールド マスクは、ターゲット リソースのどのフィールドを更新するかを指定します。 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(())
}