Migração simples do Amazon S3 para o Cloud Storage

Esta página descreve como concluir uma migração simples do Amazon Simple Storage Service (Amazon S3) para o Cloud Storage. Numa migração simples, usa as ferramentas e as bibliotecas existentes para gerar pedidos REST autenticados para o Amazon S3, de modo a enviar pedidos autenticados para o Cloud Storage.

Se não conhece o Cloud Storage e não vai usar a API diretamente, considere usar a Google Cloud consola para configurar e gerir transferências. A Google Cloud consola oferece uma interface gráfica para o Cloud Storage que lhe permite realizar muitas das suas tarefas de armazenamento usando apenas um navegador, incluindo a migração dos seus dados do Amazon S3 para o Cloud Storage.

Se quiser que o Cloud Storage armazene uma cópia de segurança dos seus dados do Amazon S3, considere usar transferências acionadas por eventos, que usam notificações de eventos do Amazon S3 para manter automaticamente um contentor do Cloud Storage sincronizado com a sua origem do Amazon S3.

Migre do Amazon S3 para o Cloud Storage num cenário de migração simples

Para fazer pedidos ao Cloud Storage, tem de concluir os seguintes passos:

  • Defina um projeto Google Cloud predefinido.
  • Obtenha uma chave HMAC (código de autenticação de mensagens baseado em hash).
  • Nas suas ferramentas ou bibliotecas existentes, faça as seguintes alterações:

    • Altere o ponto final do pedido para usar o ponto final do pedido da API XML do Cloud Storage.
    • Substitua a chave de acesso e a chave secreta dos Amazon Web Services (AWS) pelo ID de acesso e segredo do Cloud Storage (denominados coletivamente chave HMAC do Cloud Storage).
    • Certifique-se de que os cabeçalhos x-amz- usam valores do Cloud Storage suportados. Por exemplo, x-amz-storage-class deve usar uma das classes de armazenamento do Cloud Storage disponíveis.

      Quando usa a API XML do Cloud Storage num cenário de migração simples, especificar o identificador de assinatura AWS no cabeçalho Authorization permite que o Cloud Storage saiba que deve esperar cabeçalhos x-amz-* e a sintaxe XML da ACL do Amazon S3 no seu pedido. O Cloud Storage processa os cabeçalhos x-amz-* que têm um equivalente x-goog-*, como os indicados na tabela de cabeçalhos, e processa o cabeçalho x-amz-decoded-content-length.

Depois de fazer estas alterações, pode começar a usar as suas ferramentas e bibliotecas existentes para enviar pedidos HMAC para o Cloud Storage.

Por exemplo, os seguintes exemplos demonstram como listar os contentores do Cloud Storage através do SDK do Amazon S3:

Go

Para mais informações, consulte a documentação de referência da API Go do Cloud Storage.

Para se autenticar no Cloud Storage, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para bibliotecas de cliente.

import (
	"context"
	"fmt"
	"io"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"
)

func listGCSBuckets(w io.Writer, googleAccessKeyID string, googleAccessKeySecret string) error {
	// googleAccessKeyID := "Your Google Access Key ID"
	// googleAccessKeySecret := "Your Google Access Key Secret"

	// Create a new client and do the following:
	// 1. Change the endpoint URL to use the Google Cloud Storage XML API endpoint.
	// 2. Use Cloud Storage HMAC Credentials.
	sess := session.Must(session.NewSession(&aws.Config{
		Region:      aws.String("auto"),
		Endpoint:    aws.String("https://storage.googleapis.com"),
		Credentials: credentials.NewStaticCredentials(googleAccessKeyID, googleAccessKeySecret, ""),
	}))

	client := s3.New(sess)
	ctx := context.Background()

	ctx, cancel := context.WithTimeout(ctx, time.Second*10)
	defer cancel()
	result, err := client.ListBucketsWithContext(ctx, &s3.ListBucketsInput{})
	if err != nil {
		return fmt.Errorf("ListBucketsWithContext: %w", err)
	}

	fmt.Fprintf(w, "Buckets:")
	for _, b := range result.Buckets {
		fmt.Fprintf(w, "%s\n", aws.StringValue(b.Name))
	}

	return nil
}

Java

Para mais informações, consulte a documentação de referência da API Java do Cloud Storage.

Para se autenticar no Cloud Storage, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para bibliotecas de cliente.

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.Bucket;
import java.util.List;

public class ListGcsBuckets {
  public static void listGcsBuckets(String googleAccessKeyId, String googleAccessKeySecret) {

    // String googleAccessKeyId = "your-google-access-key-id";
    // String googleAccessKeySecret = "your-google-access-key-secret";

    // Create a BasicAWSCredentials using Cloud Storage HMAC credentials.
    BasicAWSCredentials googleCreds =
        new BasicAWSCredentials(googleAccessKeyId, googleAccessKeySecret);

    // Create a new client and do the following:
    // 1. Change the endpoint URL to use the Google Cloud Storage XML API endpoint.
    // 2. Use Cloud Storage HMAC Credentials.
    AmazonS3 interopClient =
        AmazonS3ClientBuilder.standard()
            .withEndpointConfiguration(
                new AwsClientBuilder.EndpointConfiguration(
                    "https://storage.googleapis.com", "auto"))
            .withCredentials(new AWSStaticCredentialsProvider(googleCreds))
            .build();

    // Call GCS to list current buckets
    List<Bucket> buckets = interopClient.listBuckets();

    // Print bucket names
    System.out.println("Buckets:");
    for (Bucket bucket : buckets) {
      System.out.println(bucket.getName());
    }

    // Explicitly clean up client resources.
    interopClient.shutdown();
  }

Python

Para mais informações, consulte a documentação de referência da API Python do Cloud Storage.

Para se autenticar no Cloud Storage, configure as Credenciais padrão da aplicação. Para mais informações, consulte o artigo Configure a autenticação para bibliotecas de cliente.

import boto3  # type: ignore


def list_gcs_buckets(
    google_access_key_id: str, google_access_key_secret: str
) -> List[str]:
    """Lists all Cloud Storage buckets using AWS SDK for Python (boto3)
    Positional arguments:
        google_access_key_id: hash-based message authentication code (HMAC) access ID
        google_access_key_secret: HMAC access secret

    Returned value is a list of strings, one for each bucket name.

    To use this sample:
    1. Create a Cloud Storage HMAC key: https://cloud.google.com/storage/docs/authentication/managing-hmackeys#create
    2. Change endpoint_url to a Google Cloud Storage XML API endpoint.

    To learn more about HMAC: https://cloud.google.com/storage/docs/authentication/hmackeys#overview
    """
    client = boto3.client(
        "s3",
        region_name="auto",
        endpoint_url="https://storage.googleapis.com",
        aws_access_key_id=google_access_key_id,
        aws_secret_access_key=google_access_key_secret,
    )

    # Call GCS to list current buckets
    response = client.list_buckets()

    # Return list of bucket names
    results = []
    for bucket in response["Buckets"]:
        results.append(bucket["Name"])
        print(bucket["Name"])  # Can remove if not needed after development
    return results

Predefina um projeto

Para usar o Cloud Storage num cenário de migração simples, recomendamos que defina um projeto predefinido, que o Cloud Storage usa para realizar determinadas operações, como o GET serviço ou o PUT contentor. Se não definir um projeto predefinido, tem de especificar um cabeçalho do projeto em determinados pedidos.

Para definir um projeto predefinido:

  1. Abra a página Definições do Cloud Storage na Google Cloud consola.
  2. Selecione o separador Interoperabilidade.
  3. Clique em Definir PROJECT-ID como projeto predefinido, localizado na secção Projeto predefinido para acesso interoperável.

    Se o projeto já for o projeto predefinido, é apresentada a mensagem PROJECT-ID é o seu projeto predefinido para acesso interoperável.

Este projeto é agora o seu projeto predefinido. Pode alterar o projeto predefinido em qualquer altura escolhendo um projeto diferente e seguindo estes passos.

Em alternativa, especifique um cabeçalho do projeto

Em vez de, ou além de, definir um projeto predefinido, pode usar o cabeçalho x-amz-project-id em pedidos individuais que exijam que especifique um projeto.

  • Um pedido que usa x-amz-project-id usa o projeto especificado no cabeçalho, mesmo que exista um projeto predefinido.

O cabeçalho x-amz-project-id é útil quando:

  • Está a trabalhar com vários projetos.
  • Os seus pedidos são feitos por uma conta de serviço associada a um projeto diferente, porque as contas de serviço usam o respetivo projeto principal como projeto predefinido.

Tenha em atenção que o Amazon S3 não tem projetos. Por isso, consoante as ferramentas ou as bibliotecas de cliente que usar, especificar um cabeçalho x-amz-project-id pode não ser uma opção. Neste caso, deve definir um projeto predefinido.

Use chaves HMAC

Para usar a API XML do Cloud Storage num cenário de migração simples, use as chaves do código de autenticação de mensagens (HMAC) baseadas em hash do Cloud Storage para as credenciais. Normalmente, deve criar uma chave HMAC associada a uma conta de serviço. No entanto, em alternativa, pode usar uma chave associada a uma conta de utilizador.

Efetue a autenticação num cenário de migração simples

Use o cabeçalho de autorização

Para operações num cenário de migração simples que requerem autenticação, inclua um cabeçalho de pedido Authorization, tal como faz para pedidos ao Amazon S3. A sintaxe do cabeçalho Authorization para um pedido do Amazon S3 é:

Authorization: AWS4-HMAC-SHA256 Credential=AWS-ACCESS-KEY/CREDENTIAL_SCOPE, SignedHeaders=SIGNED_HEADERS, Signature=SIGNATURE

Num cenário de migração simples, só tem de alterar o cabeçalho para usar o ID de acesso HMAC do Cloud Storage e certificar-se de que o Signature que anexar é calculado com a chave secreta HMAC do Cloud Storage:

Authorization: ALGORITHM Credential=GOOG-ACCESS-ID/CREDENTIAL_SCOPE, SignedHeaders=SIGNED_HEADERS, Signature=SIGNATURE

As partes do cabeçalho Authorization são:

  • ALGORITHM: o algoritmo e a versão da assinatura que está a usar. A utilização de AWS4-HMAC-SHA256 indica que está a usar uma assinatura HMAC V4 e que pretende enviar cabeçalhos x-amz-*. Também pode usar GOOG4-HMAC-SHA256, que indica que está a usar uma assinatura HMAC V4 e que pretende enviar cabeçalhos x-goog-*, ou GOOG4-RSA-SHA256, que indica que está a usar uma assinatura RSA V4 e que pretende enviar cabeçalhos x-goog-*.

  • GOOG-ACCESS-ID: o ID de acesso identifica a entidade que está a fazer e a assinar o pedido. Numa migração simples, substitua o ID da chave de acesso dos serviços Web da Amazon (AWS) que usa para aceder ao Amazon S3 pelo ID de acesso HMAC do Cloud Storage. O ID de acesso HMAC do Cloud Storage começa por GOOG.

  • CREDENTIAL_SCOPE: o âmbito das credenciais, conforme definido na assinatura. Numa migração simples, não precisa de alterar o âmbito das credenciais se estiver a usar AWS4-HMAC-SHA256 para o valor ALGORITHM.

  • SIGNED_HEADERS: uma lista de nomes de cabeçalhos separados por ponto e vírgula que têm de ser incluídos para assinar este pedido. Todos os cabeçalhos devem estar em minúsculas e ordenados por código de caráter.

    Um exemplo de uma string de cabeçalho assinada ao estilo do Amazon S3 tem o seguinte aspeto:

    content-type;host;x-amz-date

    Numa migração simples, não tem de fazer alterações à string do cabeçalho assinado.

  • SIGNATURE: A assinatura que permite a autenticação do pedido. Numa migração simples, substitua as informações da chave de acesso da AWS pelas informações da chave HMAC do Cloud Storage equivalentes.

Exemplo de pedido de autenticação

Os exemplos seguintes carregam um objeto denominado /europe/france/paris.jpg para um contentor denominado my-travel-maps, aplicam a ACL predefinida public-read e definem um cabeçalho de metadados personalizado para os revisores. Aqui está o pedido para um contentor no Amazon S3:

PUT europe/france/paris.jpg HTTP/1.1
Host: my-travel-maps.s3.amazonaws.com
Date: Mon, 11 Mar 2019 23:46:19 GMT
Content-Length: 888814
Content-Type: image/jpg
x-amz-acl: public-read
x-amz-date:20190311T192918Z
x-amz-meta-reviewer: joe,jane
Authorization: AWS4-HMAC-SHA256 Credential=AWS-ACCESS-KEY/20190311/us-east-1/s3/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-acl;x-amz-date;x-amz-meta-reviewer, Signature=SIGNATURE

Segue-se o pedido de um contentor no Cloud Storage:

PUT europe/france/paris.jpg HTTP/1.1
Host: my-travel-maps.storage.googleapis.com
Date: Mon, 11 Mar 2019 23:46:19 GMT
Content-Length: 888814
Content-Type: image/jpg
x-amz-acl: public-read
x-amz-date:20190311T192918Z
x-amz-meta-reviewer: joe,jane
Authorization: AWS4-HMAC-SHA256 Credential=GOOG-ACCESS-ID/20190311/us-east-1/s3/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-acl;x-amz-date;x-amz-meta-reviewer, Signature=SIGNATURE

Segue-se o pedido canónico correspondente que foi criado para esta solicitação:

PUT
/europe/france/paris.jpg

content-length:888814
content-type:image/jpg
host:my-travel-maps.storage.googleapis.com
x-amz-acl:public-read
x-amz-date:20190311T192918Z
x-amz-meta-reviewer:joe,jane

content-length,content-type,host,x-amz-acl,x-amz-date,x-amz-meta-reviewer
82e3da8b3f35989512e8d428add7eca73ab0e5f36586e66fbad8e1051343cbd2

Segue-se a string para assinatura correspondente que foi criada para este pedido:

AWS4-HMAC-SHA256
20190311T192918Z
20190311/us-east-1/s3/aws4_request
73918a5ff373d7a03e406fbf9ea35675396b06fca2af76c27a5c451fa783ef65

Este pedido não forneceu um cabeçalho Content-MD5, pelo que é apresentada uma string vazia na segunda linha da mensagem.

Controlo de acesso num cenário de migração simples

Para suportar migrações simples, o Cloud Storage aceita ACLs produzidas pelo Amazon S3. Num cenário de migração simples, usa AWS como identificador de assinatura, o que indica ao Cloud Storage que deve esperar a sintaxe da ACL com a sintaxe XML da ACL do Amazon S3. Deve garantir que as LCAs do Amazon S3 que usa são mapeadas para o modelo de LCA do Cloud Storage. Por exemplo, se as suas ferramentas e bibliotecas usarem a sintaxe da ACL da Amazon S3 para conceder a autorização WRITE ao contentor, também têm de conceder a autorização READ ao contentor, porque as autorizações do Cloud Storage são concêntricas. Não precisa de especificar as autorizações WRITE e READ quando concede a autorização WRITE através da sintaxe do Cloud Storage.

O Cloud Storage suporta a sintaxe de ACLs do Amazon S3 nos seguintes cenários:

  • Num pedido ao Cloud Storage para obter LCAs (por exemplo, um pedido de GET objeto ou GET recipiente), o Cloud Storage devolve a sintaxe de LCA da Amazon S3.
  • Num pedido ao Cloud Storage para aplicar LCAs (por exemplo, um pedido de PUT objeto ou de contentor), o Cloud Storage espera receber a sintaxe de LCA do Amazon S3.PUT

O cabeçalho Authorization num cenário de migração simples usa AWS para o identificador de assinatura, mas com o ID de acesso HMAC do Cloud Storage.

Authorization: AWS4-HMAC-SHA256 Credential=GOOG-ACCESS-ID/CREDENTIAL_SCOPE, SignedHeaders=SIGNED_HEADERS, Signature=SIGNATURE

O exemplo seguinte mostra um pedido GET ao Cloud Storage para devolver as LCAs de um objeto.

GET europe/france/paris.jpg?acl HTTP/1.1
Host: my-travel-maps.storage.googleapis.com
Date: Thu, 21 Feb 2019 23:50:10 GMT
Content-Type: application/xml
X-Amz-Date: 20190221T235010Z
Authorization: AWS4-HMAC-SHA256 Credential=GOOGMC5PDPA5JLZYQMHQHRAX/20190221/region/s3/aws4_request, SignedHeaders=host;x-amz-date, Signature=29088b1d6dfeb2549f6ff67bc3744abb7e45475f0ad60400485805415bbfc534

A resposta ao pedido inclui a ACL através da sintaxe da ACL do Amazon S3.

<?xml version='1.0' encoding='UTF-8'?>
<AccessControlPolicy>
    <Owner>
        <ID>00b4903a972faa8bcce9382686e9129676f1cd6e5def1f5663affc2ba4652490
        </ID>
        <DisplayName>OwnerName</DisplayName>
    </Owner>
    <AccessControlList>
        <Grant>
            <Grantee xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
                xsi:type='CanonicalUser'>
                <ID>00b4903a972faa8bcce9382686e9129676f1cd6e5def1f5663affc2ba4652490</ID>
                <DisplayName>UserName</DisplayName>
            </Grantee>
            <Permission>FULL_CONTROL</Permission>
        </Grant>
    </AccessControlList>
</AccessControlPolicy>

O exemplo seguinte mostra um pedido PUT ao Cloud Storage para definir as LCAs de um objeto. O exemplo mostra um corpo do pedido com a sintaxe da ACL do Amazon S3.

PUT europe/france/paris.jpg?acl HTTP/1.1
Host: my-travel-maps.storage.googleapis.com
Date: Thu, 21 Feb 2019 23:50:10 GMT
Content-Type: application/xml
Content-Length: 337
X-Amz-Date: 20190221T235010Z
Authorization: AWS4-HMAC-SHA256 Credential=GOOGMC5PDPA5JLZYQMHQHRAX/20190221/region/s3/aws4_request, SignedHeaders=host;x-amz-date, Signature=29088b1d6dfeb2549f6ff67bc3744abb7e45475f0ad60400485805415bbfc534

<?xml version='1.0' encoding='utf-8'?>
<AccessControlPolicy>
  <AccessControlList>
    <Grant>
      <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="AmazonCustomerByEmail">
        <EmailAddress>jeffersonloveshiking@gmail.com</EmailAddress>
      </Grantee>
      <Permission>FULL_CONTROL</Permission>
    </Grant>
  </AccessControlList>
</AccessControlPolicy>

Por último, num cenário de migração simples, também pode usar o identificador de assinatura GOOG1 no cabeçalho Authorization. Neste caso, tem de usar a sintaxe da ACL do Cloud Storage e garantir que todos os cabeçalhos x-amz-* são alterados para x-goog-*. Embora seja possível, recomendamos que escolha uma migração completa para usar todas as vantagens do Cloud Storage.

Suporte para compatibilidade da API XML com o Amazon S3

Para discussões sobre a interoperabilidade da API XML, consulte o Stack Overflow com a etiqueta google-cloud-storage.

O que se segue?