Disabilita l'eliminazione temporanea

Panoramica sull'utilizzo

Questa pagina descrive come disattivare la funzionalità di eliminazione temporanea sui bucket nuovi ed esistenti della tua organizzazione.

L'eliminazione temporanea è abilitata per impostazione predefinita sui nuovi bucket per evitare la perdita di dati. Se necessario, puoi disattivare l'eliminazione temporanea per i bucket esistenti modificando la policy di eliminazione temporanea e puoi disattivare l'eliminazione temporanea per impostazione predefinita per i nuovi bucket impostando un tag predefinito a livello di organizzazione. Tieni presente che, una volta disattivata l'eliminazione temporanea, i dati eliminati non possono essere recuperati, incluse le eliminazioni accidentali o dannose.

Ruoli obbligatori

Per ottenere le autorizzazioni necessarie per disattivare l'eliminazione temporanea, chiedi all'amministratore di concederti i seguenti ruoli IAM a livello di organizzazione:

Questi ruoli predefiniti contengono le autorizzazioni necessarie per disattivare l'eliminazione temporanea. Per vedere quali sono esattamente le autorizzazioni richieste, espandi la sezione Autorizzazioni obbligatorie:

Autorizzazioni obbligatorie

Per disattivare l'eliminazione temporanea sono necessarie le seguenti autorizzazioni:

  • storage.buckets.get
  • storage.buckets.update
  • storage.buckets.list (questa autorizzazione è necessaria solo se prevedi di utilizzare la Google Cloud console per eseguire le istruzioni riportate in questa pagina)

    Per le autorizzazioni obbligatorie incluse nel ruolo Tag Admin(roles/resourcemanager.tagAdmin), consultaAutorizzazioni obbligatorie per l'amministrazione dei tag.

Per informazioni sulla concessione dei ruoli, consulta Impostare e gestire le policy IAM sui bucket o Gestire l'accesso ai progetti.

Disattivare l'eliminazione temporanea per un bucket specifico

Prima di iniziare, tieni presente quanto segue:

  • Se disattivi una policy di eliminazione temporanea da un bucket che contiene oggetti eliminati temporaneamente durante il periodo di disattivazione, gli oggetti eliminati temporaneamente esistenti vengono conservati fino alla scadenza della durata di conservazione applicata in precedenza.

  • Dopo aver disattivato una policy di eliminazione temporanea sul bucket, Cloud Storage non conserva gli oggetti eliminati di recente.

  • Quando disattivi una policy di eliminazione temporanea sul bucket, la modifica non è immediata in Cloud Storage a causa della memorizzazione nella cache dei metadati. Pertanto, ti consigliamo di attendere almeno trenta secondi prima di avviare altre operazioni di eliminazione, ad esempio l'eliminazione collettiva, dopo aver disattivato una policy di eliminazione temporanea. In questo modo, i dati vengono eliminati in modo permanente anziché temporaneamente. Per saperne di più sulla coerenza delle operazioni di Cloud Storage, consulta Coerenza di Cloud Storage.

Segui queste istruzioni per disattivare l'eliminazione temporanea per un bucket specifico:

Console

  1. Nella Google Cloud console, vai alla pagina Bucket in Cloud Storage.

    Vai a Bucket

  2. Nell'elenco dei bucket, fai clic sul nome del bucket di cui vuoi disattivare la policy di eliminazione temporanea.

  3. Fai clic sulla scheda Protezione.

  4. Nella sezione Policy di eliminazione temporanea, fai clic su Disattiva per disattivare la policy di eliminazione temporanea.

  5. Fai clic su Conferma.

Per scoprire come ottenere informazioni dettagliate sugli errori relativi alle operazioni di Cloud Storage non riuscite nella Google Cloud console, consulta Risoluzione dei problemi.

Riga di comando

Esegui il gcloud storage buckets update comando con il --clear-soft-delete flag:

gcloud storage buckets update --clear-soft-delete gs://BUCKET_NAME

Dove:

  • BUCKET_NAME è il nome del bucket. Ad esempio, my-bucket.

API REST

API JSON

  1. Assicurati di aver installato e inizializzato gcloud CLI installato e inizializzato, che ti consente di generare un token di accesso per l'intestazione Authorization.

  2. Crea un file JSON contenente le seguenti informazioni:

    {
      "softDeletePolicy": {
        "retentionDurationSeconds": "0"
      }
    }
  3. Utilizza cURL per chiamare l'API JSON con una PATCH Bucket request:

    curl -X PATCH --data-binary @JSON_FILE_NAME \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: application/json" \
      "https://storage.googleapis.com/storage/v1/b/BUCKET_NAME"

    Dove:

    • JSON_FILE_NAME è il percorso del file JSON che hai creato nel passaggio 2.
    • BUCKET_NAME è il nome del bucket pertinente. Ad esempio, my-bucket.

Disattivare l'eliminazione temporanea per i 100 bucket più grandi di un progetto

Utilizzando la Google Cloud console, puoi disattivare l'eliminazione temporanea per un massimo di 100 bucket contemporaneamente, con i bucket ordinati in base al numero maggiore di byte eliminati temporaneamente o al rapporto più alto tra byte eliminati temporaneamente e byte attivi, il che ti consente di gestire i bucket con il maggiore impatto sui costi di eliminazione temporanea.

  1. Nella Google Cloud console, vai alla pagina Bucket in Cloud Storage.

    Vai a Bucket

  2. Nella pagina Cloud Storage, fai clic su Impostazioni.

  3. Fai clic sulla scheda Eliminazione temporanea.

  4. Nell'elenco Bucket principali per byte eliminati, seleziona i bucket per cui vuoi disattivare l'eliminazione temporanea.

  5. Fai clic su Disattiva l'eliminazione temporanea.

    L'eliminazione temporanea è disattivata sui bucket selezionati.

Disattivare l'eliminazione temporanea per più bucket o per tutti i bucket di un progetto

Utilizzando Google Cloud CLI, esegui il gcloud storage buckets update comando con il --project flag e il * carattere jolly per disattivare collettivamente l'eliminazione temporanea per più bucket o per tutti i bucket di un progetto:

gcloud storage buckets update --project=PROJECT_ID --clear-soft-delete gs://*

Dove:

  • PROJECT_ID è l'ID del progetto. Ad esempio, my-project.

Disattivare l'eliminazione temporanea per tutti i bucket di una cartella

Utilizzando Google Cloud CLI, esegui i comandi gcloud projects list e gcloud storage buckets update per disattivare l'eliminazione temporanea sui bucket di tutti i progetti in una cartella specificata.

Esegui i gcloud projects list e gcloud storage buckets update comandi per elencare tutti i bucket in una cartella specificata e poi disattivare l'eliminazione temporanea per tutti i bucket della cartella:

gcloud projects list --filter="parent.id: FOLDER_ID" --format="value(projectId)" | while read project
do
  gcloud storage buckets update --project=$project --clear-soft-delete gs://*
done

Dove:

  • FOLDER_ID è il nome della cartella. Ad esempio, 123456.

Disattivare l'eliminazione temporanea a livello di organizzazione

Utilizzando Google Cloud CLI, esegui il gcloud storage buckets update comando con il --clear-soft-delete flag e il * carattere jolly per disattivare l'eliminazione temporanea a livello di organizzazione:

Esegui il gcloud storage buckets update comando con il --clear-soft-delete flag e il * carattere jolly per disattivare l'eliminazione temporanea per tutti i bucket della tua organizzazione:

gcloud projects list --format="value(projectId)" | while read project
do
  gcloud storage buckets update --project=$project --clear-soft-delete gs://*
done

Cloud Storage disattiva l'eliminazione temporanea sui bucket esistenti. Gli oggetti che sono già stati eliminati temporaneamente rimarranno nei bucket fino al completamento della durata di conservazione dell'eliminazione temporanea, dopodiché verranno eliminati definitivamente.

Disattivare l'eliminazione temporanea per i nuovi bucket

Anche se l'eliminazione temporanea è abilitata per impostazione predefinita sui nuovi bucket, puoi impedire l'abilitazione predefinita dell'eliminazione temporanea utilizzando i tag. I tag utilizzano la chiave storage.defaultSoftDeletePolicy per applicare una policy di eliminazione temporanea di 0d (zero giorni) a livello di organizzazione, che disattiva la funzionalità e impedisce la conservazione futura dei dati eliminati.

Segui queste istruzioni per disattivare l'eliminazione temporanea per impostazione predefinita quando crei nuovi bucket. Tieni presente che le seguenti istruzioni non sono equivalenti all'impostazione di una policy dell'organizzazione che impone una determinata policy di eliminazione temporanea, il che significa che puoi comunque abilitare l'eliminazione temporanea su bucket specifici specificando una policy, se necessario.

  1. Utilizzando Google Cloud CLI, crea il tag storage.defaultSoftDeletePolicy utilizzato per modificare la durata di conservazione dell'eliminazione temporanea predefinita sui nuovi bucket. Tieni presente che solo il nome del tag storage.defaultSoftDeletePolicy aggiorna la durata di conservazione dell'eliminazione temporanea predefinita.

    Crea una chiave tag utilizzando il gcloud resource-manager tags keys create comando:

    gcloud resource-manager tags keys create storage.defaultSoftDeletePolicy \
     --parent=organizations/ORGANIZATION_ID \
     --description="Configures the default softDeletePolicy for new Storage buckets."
    

    Dove:

    • ORGANIZATION_ID è l'ID numerico dell'organizzazione per cui vuoi impostare una durata di conservazione dell'eliminazione temporanea predefinita. Ad esempio, 12345678901. Per scoprire come trovare l'ID organizzazione, consulta Recuperare l'ID risorsa dell'organizzazione.
  2. Crea un valore tag per 0d (zero giorni) per disattivare il periodo di conservazione dell'eliminazione temporanea per impostazione predefinita sui nuovi bucket utilizzando il gcloud resource-manager tags values create comando:

    gcloud resource-manager tags values create 0d \
      --parent=ORGANIZATION_ID/storage.defaultSoftDeletePolicy \
      --description="Disables soft delete for new Storage buckets."
    

    Dove:

    • ORGANIZATION_ID è l'ID numerico dell'organizzazione per cui vuoi impostare la durata di conservazione dell'eliminazione temporanea predefinita. Ad esempio, 12345678901.
  3. Collega il tag alla risorsa utilizzando il gcloud resource-manager tags bindings create comando:

    gcloud resource-manager tags bindings create \
     --tag-value=ORGANIZATION_ID/storage.defaultSoftDeletePolicy/0d \
     --parent=RESOURCE_ID
    

    Dove:

    • ORGANIZATION_ID è l'ID numerico dell'organizzazione in cui è stato creato il tag. Ad esempio, 12345678901.

    • RESOURCE_ID è il nome completo dell'organizzazione per cui vuoi creare l'associazione di tag. Ad esempio, per collegare un tag a organizations/7890123456, inserisci //cloudresourcemanager.googleapis.com/organizations/7890123456.

Disattivare l'eliminazione temporanea per i bucket che superano una soglia di costo specificata

Utilizzando le librerie client di Cloud per Python, puoi disattivare l'eliminazione temporanea per i bucket che superano una soglia di costo relativa specificata con un esempio di libreria client Python. L'esempio esegue le seguenti operazioni:

  1. Calcola il costo relativo dello spazio di archiviazione per ogni classe di archiviazione.

  2. Valuta il costo di eliminazione temporanea accumulato dai bucket.

  3. Imposta una soglia di costo per l'utilizzo dell'eliminazione temporanea ed elenca i bucket che superano la soglia impostata e ti consente di disattivare l'eliminazione temporanea per i bucket che superano la soglia.

Per saperne di più sulla configurazione della libreria client Python e sull'utilizzo dell'esempio, consulta la pagina README.md dell'analizzatore dei costi di eliminazione temporanea di Cloud Storage.

L'esempio seguente disattiva l'eliminazione temporanea per i bucket che superano una soglia di costo specificata:

from __future__ import annotations

import argparse
import json
import google.cloud.monitoring_v3 as monitoring_client


def get_relative_cost(storage_class: str) -> float:
    """Retrieves the relative cost for a given storage class and location.

    Args:
        storage_class: The storage class (e.g., 'standard', 'nearline').

    Returns:
        The price per GB from the https://cloud.google.com/storage/pricing,
        divided by the standard storage class.
    """
    relative_cost = {
        "STANDARD": 0.023 / 0.023,
        "NEARLINE": 0.013 / 0.023,
        "COLDLINE": 0.007 / 0.023,
        "ARCHIVE": 0.0025 / 0.023,
    }

    return relative_cost.get(storage_class, 1.0)


def get_soft_delete_cost(
    project_name: str,
    soft_delete_window: float,
    agg_days: int,
    lookback_days: int,
) -> dict[str, list[dict[str, float]]]:
    """Calculates soft delete costs for buckets in a Google Cloud project.

    Args:
        project_name: The name of the Google Cloud project.
        soft_delete_window: The time window in seconds for considering
          soft-deleted objects (default is 7 days).
        agg_days: Aggregate results over a time period, defaults to 30-day period
        lookback_days: Look back up to upto days, defaults to 360 days

    Returns:
        A dictionary with bucket names as keys and cost data for each bucket,
        broken down by storage class.
    """

    query_client = monitoring_client.QueryServiceClient()

    # Step 1: Get storage class ratios for each bucket.
    storage_ratios_by_bucket = get_storage_class_ratio(
        project_name, query_client, agg_days, lookback_days
    )

    # Step 2: Fetch soft-deleted bytes and calculate costs using Monitoring API.
    soft_deleted_costs = calculate_soft_delete_costs(
        project_name,
        query_client,
        soft_delete_window,
        storage_ratios_by_bucket,
        agg_days,
        lookback_days,
    )

    return soft_deleted_costs


def calculate_soft_delete_costs(
    project_name: str,
    query_client: monitoring_client.QueryServiceClient,
    soft_delete_window: float,
    storage_ratios_by_bucket: dict[str, float],
    agg_days: int,
    lookback_days: int,
) -> dict[str, list[dict[str, float]]]:
    """Calculates the relative cost of enabling soft delete for each bucket in a
       project for certain time frame in secs.

    Args:
        project_name: The name of the Google Cloud project.
        query_client: A Monitoring API query client.
        soft_delete_window: The time window in seconds for considering
          soft-deleted objects (default is 7 days).
        storage_ratios_by_bucket: A dictionary of storage class ratios per bucket.
        agg_days: Aggregate results over a time period, defaults to 30-day period
        lookback_days: Look back up to upto days, defaults to 360 days

    Returns:
        A dictionary with bucket names as keys and a list of cost data
        dictionaries
        for each bucket, broken down by storage class.
    """
    soft_deleted_bytes_time = query_client.query_time_series(
        monitoring_client.QueryTimeSeriesRequest(
            name=f"projects/{project_name}",
            query=f"""
                    {{  # Fetch 1: Soft-deleted (bytes seconds)
                        fetch gcs_bucket :: storage.googleapis.com/storage/v2/deleted_bytes
                        | value val(0) * {soft_delete_window}\'s\'  # Multiply by soft delete window
                        | group_by [resource.bucket_name, metric.storage_class], window(), .sum;

                        # Fetch 2: Total byte-seconds (active objects)
                        fetch gcs_bucket :: storage.googleapis.com/storage/v2/total_byte_seconds
                        | filter metric.type != 'soft-deleted-object'
                        | group_by [resource.bucket_name, metric.storage_class], window(1d), .mean  # Daily average
                        | group_by [resource.bucket_name, metric.storage_class], window(), .sum  # Total over window

                    }}  # End query definition
                    | every {agg_days}d  # Aggregate over larger time intervals
                    | within {lookback_days}d  # Limit data range for analysis
                    | ratio  # Calculate ratio (soft-deleted (bytes seconds)/ total (bytes seconds))
                    """,
        )
    )

    buckets: dict[str, list[dict[str, float]]] = {}
    missing_distribution_storage_class = []
    for data_point in soft_deleted_bytes_time.time_series_data:
        bucket_name = data_point.label_values[0].string_value
        storage_class = data_point.label_values[1].string_value
        # To include location-based cost analysis:
        # 1. Uncomment the line below:
        # location = data_point.label_values[2].string_value
        # 2. Update how you calculate 'relative_storage_class_cost' to factor in location
        soft_delete_ratio = data_point.point_data[0].values[0].double_value
        distribution_storage_class = bucket_name + " - " + storage_class
        storage_class_ratio = storage_ratios_by_bucket.get(
            distribution_storage_class
        )
        if storage_class_ratio is None:
            missing_distribution_storage_class.append(
                distribution_storage_class)
        buckets.setdefault(bucket_name, []).append({
            # Include storage class and location data for additional plotting dimensions.
            # "storage_class": storage_class,
            # 'location': location,
            "soft_delete_ratio": soft_delete_ratio,
            "storage_class_ratio": storage_class_ratio,
            "relative_storage_class_cost": get_relative_cost(storage_class),
        })

    if missing_distribution_storage_class:
        print(
            "Missing storage class for following buckets:",
            missing_distribution_storage_class,
        )
        raise ValueError("Cannot proceed with missing storage class ratios.")

    return buckets


def get_storage_class_ratio(
    project_name: str,
    query_client: monitoring_client.QueryServiceClient,
    agg_days: int,
    lookback_days: int,
) -> dict[str, float]:
    """Calculates storage class ratios for each bucket in a project.

    This information helps determine the relative cost contribution of each
    storage class to the overall soft-delete cost.

    Args:
        project_name: The Google Cloud project name.
        query_client: Google Cloud's Monitoring Client's QueryServiceClient.
        agg_days: Aggregate results over a time period, defaults to 30-day period
        lookback_days: Look back up to upto days, defaults to 360 days

    Returns:
        Ratio of Storage classes within a bucket.
    """
    request = monitoring_client.QueryTimeSeriesRequest(
        name=f"projects/{project_name}",
        query=f"""
            {{
            # Fetch total byte-seconds for each bucket and storage class
            fetch gcs_bucket :: storage.googleapis.com/storage/v2/total_byte_seconds
            | group_by [resource.bucket_name, metric.storage_class], window(), .sum;
            # Fetch total byte-seconds for each bucket (regardless of class)
            fetch gcs_bucket :: storage.googleapis.com/storage/v2/total_byte_seconds
            | group_by [resource.bucket_name], window(), .sum
            }}
            | ratio  # Calculate ratios of storage class size to total size
            | every {agg_days}d
            | within {lookback_days}d
            """,
    )

    storage_class_ratio = query_client.query_time_series(request)

    storage_ratios_by_bucket = {}
    for time_series in storage_class_ratio.time_series_data:
        bucket_name = time_series.label_values[0].string_value
        storage_class = time_series.label_values[1].string_value
        ratio = time_series.point_data[0].values[0].double_value

        # Create a descriptive key for the dictionary
        key = f"{bucket_name} - {storage_class}"
        storage_ratios_by_bucket[key] = ratio

    return storage_ratios_by_bucket


def soft_delete_relative_cost_analyzer(
    project_name: str,
    cost_threshold: float = 0.0,
    soft_delete_window: float = 604800,
    agg_days: int = 30,
    lookback_days: int = 360,
    list_buckets: bool = False,
    ) -> str | dict[str, float]: # Note potential string output
    """Identifies buckets exceeding the relative cost threshold for enabling soft delete.

    Args:
        project_name: The Google Cloud project name.
        cost_threshold: Threshold above which to consider removing soft delete.
        soft_delete_window: Time window for calculating soft-delete costs (in
          seconds).
        agg_days: Aggregate results over this time period (in days).
        lookback_days: Look back up to this many days.
        list_buckets: Return a list of bucket names (True) or JSON (False,
          default).

    Returns:
        JSON formatted results of buckets exceeding the threshold and costs
        *or* a space-separated string of bucket names.
    """

    buckets: dict[str, float] = {}
    for bucket_name, storage_sources in get_soft_delete_cost(
        project_name, soft_delete_window, agg_days, lookback_days
    ).items():
        bucket_cost = 0.0
        for storage_source in storage_sources:
            bucket_cost += (
                storage_source["soft_delete_ratio"]
                * storage_source["storage_class_ratio"]
                * storage_source["relative_storage_class_cost"]
            )
        if bucket_cost > cost_threshold:
            buckets[bucket_name] = round(bucket_cost, 4)

    if list_buckets:
        return " ".join(buckets.keys())  # Space-separated bucket names
    else:
        return json.dumps(buckets, indent=2)  # JSON output


def soft_delete_relative_cost_analyzer_main() -> None:
    # Sample run: python storage_soft_delete_relative_cost_analyzer.py <Project Name>
    parser = argparse.ArgumentParser(
        description="Analyze and manage Google Cloud Storage soft-delete costs."
    )
    parser.add_argument(
        "project_name", help="The name of the Google Cloud project to analyze."
    )
    parser.add_argument(
        "--cost_threshold",
        type=float,
        default=0.0,
        help="Relative Cost threshold.",
    )
    parser.add_argument(
        "--soft_delete_window",
        type=float,
        default=604800.0,
        help="Time window (in seconds) for considering soft-deleted objects.",
    )
    parser.add_argument(
        "--agg_days",
        type=int,
        default=30,
        help=(
            "Time window (in days) for aggregating results over a time period,"
            " defaults to 30-day period"
        ),
    )
    parser.add_argument(
        "--lookback_days",
        type=int,
        default=360,
        help=(
            "Time window (in days) for considering the how old the bucket to be."
        ),
    )
    parser.add_argument(
        "--list",
        type=bool,
        default=False,
        help="Return the list of bucketnames seperated by space.",
    )

    args = parser.parse_args()

    response = soft_delete_relative_cost_analyzer(
        args.project_name,
        args.cost_threshold,
        args.soft_delete_window,
        args.agg_days,
        args.lookback_days,
        args.list,
    )
    if not args.list:
        print(
            "To remove soft-delete policy from the listed buckets run:\n"
            # Capture output
            "python storage_soft_delete_relative_cost_analyzer.py"
            " [your-project-name] --[OTHER_OPTIONS] --list > list_of_buckets.txt \n"
            "cat list_of_buckets.txt | gcloud storage buckets update -I "
            "--clear-soft-delete",
            response,
        )
        return
    print(response)


if __name__ == "__main__":
    soft_delete_relative_cost_analyzer_main()

Passaggi successivi