Mettre à jour une ressource à l'aide d'un masque de champ

Découvrez comment mettre à jour sélectivement des ressources à l'aide de masques de champ. Lorsque vous mettez à jour une ressource dans Google Cloud, vous pouvez choisir de ne modifier que certains champs plutôt que de remplacer l'intégralité de la ressource. Les bibliothèques clientes Rust sont compatibles avec les masques de champ, ce qui vous permet de contrôler précisément les champs d'une ressource qui sont mis à jour, tout en laissant les autres champs inchangés.

Prérequis

Ce guide utilise l'API Secret Manager, mais les concepts s'appliquent à d'autres ressources et services Google Cloud .

Avant de continuer, suivez Créer un secret et y accéder à l'aide de Secret Manager pour activer l'API Secret Manager et vous authentifier.

Pour obtenir des instructions de configuration complètes pour les bibliothèques Rust, consultez Configurer votre environnement de développement.

Dépendances

Après avoir activé Secret Manager, déclarez vos dépendances dans votre fichier Cargo.toml :

cargo add google-cloud-secretmanager-v1
cargo add tokio

Installer des types connus

La crate google_cloud_wkt contient des types connus pour les API Google Cloud . Ces types ont généralement un encodage JSON personnalisé et peuvent fournir des fonctions de conversion vers et depuis les types Rust couramment utilisés. La caisse google_cloud_wkt contient le type de masque de champ, FieldMask.

Ajoutez la caisse en tant que dépendance :

cargo add google-cloud-wkt

Masques de champ

Un FieldMask représente un ensemble de chemins de champs symboliques. Les masques de champ spécifient un sous-ensemble de champs qu'une opération de mise à jour modifie ou qu'une opération d'obtention renvoie.

Lors d'une opération de mise à jour, un masque de champ spécifie les champs de la ressource cible à mettre à jour. L'API ne modifie que les valeurs des champs spécifiés dans le masque et laisse les autres intacts. Si vous transmettez une ressource pour décrire les valeurs mises à jour, l'API ignore les valeurs de tous les champs non couverts par le masque. Si vous ne fournissez pas de masque de champ lors de la mise à jour, l'opération s'applique à tous les champs.

Pour réinitialiser un champ à sa valeur par défaut, incluez-le dans le masque et définissez la valeur par défaut dans la ressource fournie. Pour réinitialiser tous les champs d'une ressource, fournissez une instance par défaut de la ressource et définissez tous les champs dans le masque, ou ne fournissez pas de masque.

Mettre à jour les champs d'une ressource

Commencez par initialiser un client Secret Manager et à créer un 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:?}");

Le résultat de l'opération de création indique que les champs labels et annotations sont vides.

Le code suivant met à jour les champs labels et 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:?}");

La méthode set_etag vous permet de définir un etag sur le secret, ce qui empêche l'écrasement des mises à jour simultanées.

Après avoir défini des libellés et des annotations sur le secret mis à jour, vous transmettez un masque de champ à set_update_mask pour spécifier les chemins d'accès aux champs à mettre à jour :

        .set_update_mask(FieldMask::default().set_paths(["annotations", "labels"]))

Le résultat de l'opération de mise à jour indique que les champs ont été mis à jour :

labels: {"updated": "your-label"},
...
annotations: {"updated": "your-annotations"},

Mettre à jour un champ : code complet

Cet exemple de code initialise et crée un secret, puis applique un masque de champ :

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(())
}