העברה פשוטה מ-Amazon S3 ל-Cloud Storage

המאמר הזה מתאר איך לבצע העברה פשוטה מ-Amazon Simple Storage Service (Amazon S3) ל-Cloud Storage. בהעברה פשוטה, משתמשים בכלים ובספריות הקיימים ליצירת בקשות REST מאומתות ל-Amazon S3, כדי לשלוח בקשות מאומתות ל-Cloud Storage.

אם אתם משתמשים חדשים ב-Cloud Storage ולא תשתמשו ישירות ב-API, אפשר להשתמש במסוף Google Cloud כדי להגדיר העברות ולנהל אותן.Google Cloud המסוף מספק ממשק גרפי ל-Cloud Storage, שמאפשר לבצע הרבה ממשימות האחסון באמצעות דפדפן, כולל העברה של נתונים מ-Amazon S3 ל-Cloud Storage.

אם רוצים ש-Cloud Storage יאחסן גיבוי של נתוני Amazon S3, כדאי להשתמש בהעברות מבוססות-אירועים, המשתמשות בהתראות אירועים של Amazon S3 כדי לסנכרן באופן אוטומטי קטגוריה של Cloud Storage למקור של Amazon S3.

העברה מ-Amazon S3 ל-Cloud Storage בתרחיש העברה פשוט

כדי לשלוח בקשות ל-Cloud Storage, צריך לבצע את השלבים הבאים:

אחרי ביצוע השינויים האלו, אפשר להתחיל את השימוש בכלים ובספריות הקיימים כדי לשלוח בקשות HMAC ל-Cloud Storage.

הדוגמאות הבאות מציגות איך ליצור רשימה של קטגוריות של Cloud Storage באמצעות ה-SDK של Amazon S3:

Go

מידע נוסף מופיע בחומרי העזר של Cloud Storage Go API.

כדי לבצע אימות ב-Cloud Storage, אתם צריכים להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

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

למידע נוסף, קראו את מאמרי העזרה של Cloud Storage Java API.

כדי לבצע אימות ב-Cloud Storage, אתם צריכים להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

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

למידע נוסף, קראו את מאמרי העזרה של Cloud Storage Python API.

כדי לבצע אימות ב-Cloud Storage, אתם צריכים להגדיר את Application Default Credentials. מידע נוסף זמין במאמר הגדרת אימות לספריות לקוח.

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

הגדרת פרויקט ברירת מחדל

כדי להשתמש ב-Cloud Storage בתרחיש העברה פשוט, מומלץ להגדיר פרויקט ברירת מחדל, שישמש את Cloud Storage לביצוע פעולות מסוימות, כמו שירות של GET או קטגוריה של PUT. אם לא מגדירים פרויקט ברירת מחדל, בבקשות מסוימות צריך לציין את כותרת הפרויקט.

כדי להגדיר פרויקט ברירת מחדל:

  1. פותחים את הדף Cloud Storage Settings במסוףGoogle Cloud .
  2. בוחרים בכרטיסייה Interoperability.
  3. לוחצים על Set PROJECT-ID as default project, שנמצא בסעיף Default project for interoperable access.

    אם הפרויקט כבר מוגדר כפרויקט ברירת מחדל, יופיע הערך PROJECT-ID is your default project for interoperable access.

הפרויקט הזה הוא עכשיו פרויקט ברירת המחדל שלכם. אפשר לשנות את פרויקט ברירת המחדל בכל שלב, על ידי בחירת פרויקט אחר וביצוע השלבים הבאים.

במקום זאת, אפשר לציין כותרת של פרויקט

במקום להגדיר פרויקט ברירת מחדל או בנוסף לו, אפשר להשתמש בכותרת x-amz-project-id בבקשות ספציפיות שבהן צריך לציין פרויקט.

  • בקשה עם x-amz-project-id משתמשת בפרויקט שצוין בכותרת, גם אם קיים פרויקט ברירת מחדל.

הכותרת x-amz-project-id מועילה כאשר:

  • עובדים עם מספר פרויקטים.
  • הבקשות נשלחות באמצעות חשבון שירות המשויך לפרויקט אחר, כי חשבונות השירות משתמשים בפרויקט ההורה שלהם כפרויקט ברירת המחדל.

שימו לב שב-Amazon S3 אין פרויקטים, כך שבהתאם לכלים או לספריות הלקוח שבהם משתמשים, לא בטוח שאפשר לציין כותרת x-amz-project-id. במקרה כזה, צריך להגדיר פרויקט ברירת מחדל.

שימוש במפתחות HMAC

כדי להשתמש ב-Cloud Storage XML API בתרחיש העברה פשוט, צריך להשתמש במפתחות של קוד אימות הודעות (HMAC) מבוססי גיבוב של Cloud Storage לפרטי הכניסה. בדרך כלל, צריך ליצור מפתח HMAC המשויך לחשבון שירות. אבל אפשר גם להשתמש במפתח המשויך לחשבון משתמש.

אימות בתרחיש העברה פשוט

שימוש בכותרת Authorization

בשביל פעולות בתרחיש העברה פשוט המחייבות אימות, צריך לכלול כותרת בקשה של Authorization, בדיוק כמו לבקשות אל Amazon S3. תחביר הכותרת Authorization לבקשת Amazon S3 הוא:

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

בתרחיש העברה פשוט, משנים את הכותרת כדי שתשתמש במזהה הגישה של Cloud Storage HMAC, ומוודאים שה-Signature שמצרפים מחושב באמצעות המפתח הסודי של Cloud Storage HMAC:

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

החלקים של הכותרת של Authorization הם:

  • ALGORITHM: אלגוריתם וגרסת החתימה שבה משתמשים. שימוש ב-AWS4-HMAC-SHA256, מציין שמשתמשים בחתימת HMAC V4 ומתכוונים לשלוח כותרות x-amz-*. אפשר גם להשתמש ב-GOOG4-HMAC-SHA256, שמציין שמשתמשים בחתימת HMAC V4 ומתכוונים לשלוח כותרות x-goog-*, או ב-GOOG4-RSA-SHA256, שמציין שמשתמשים בחתימת RSA V4 ומתכוונים לשלוח כותרות x-goog-*.

  • GOOG-ACCESS-ID: מזהה הגישה משמש לזיהוי הישות שמייצרת את הבקשה וחותמת עליה. בהעברה פשוטה, צריך להחליף את מזהה מפתח הגישה של Amazon Web Service (AWS) שבו משתמשים כדי לגשת ל-Amazon S3 באמצעות מזהה הגישה של Cloud Storage HMAC. מזהה הגישה של Cloud Storage HMAC מתחיל ב-GOOG.

  • CREDENTIAL_SCOPE: ההיקף של פרטי הכניסה, כפי שמוגדר בחתימה. בהעברה פשוטה אין צורך לשנות את ההיקף של פרטי הכניסה אם משתמשים ב-AWS4-HMAC-SHA256 כערך ALGORITHM.

  • SIGNED_HEADERS: רשימת שמות של כותרות שמופרדים באמצעות נקודה-פסיק שנחוצים כדי לחתום על הבקשה הזו. כל הכותרות צריכות להיות באותיות קטנות וממוינות לפי קודי תווים.

    דוגמה למחרוזת כותרת חתומה בסגנון Amazon S3 נראית כך:

    content-type;host;x-amz-date

    בהעברה פשוטה לא צריך לבצע שינויים במחרוזת הכותרת החתומה.

  • SIGNATURE: החתימה שמאפשרת אימות של הבקשה. בהעברה פשוטה, צריך להחליף את פרטי מפתח הגישה של AWS בפרטים המקבילים של מפתח HMAC של Cloud Storage.

בקשת אימות לדוגמה

בדוגמאות הבאות מועלה אובייקט בשם /europe/france/paris.jpg לקטגוריה בשם my-travel-maps, מחילים את ה-ACL המוגדר מראש public-read ומגדירים כותרת מטא-נתונים מותאמת אישית לבודקים. זוהי הבקשה לקטגוריה ב-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

זוהי הבקשה לקטגוריה ב-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

זוהי הבקשה הקנונית המתאימה שנוצרה עבור הבקשה הזו:

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

זוהי המחרוזת המתאימה לחתימה שנוצרה עבור הבקשה הזו:

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

הבקשה הזו לא הכילה כותרת Content-MD5, ולכן מופיעה מחרוזת ריקה בשורה השנייה של ההודעה.

בקרת גישה בתרחיש העברה פשוטה

כדי לתמוך בהעברות פשוטות, Cloud Storage מקבל רשימות ACL שנוצרו על ידי Amazon S3. בתרחיש העברה פשוט, משתמשים ב-AWS כמזהה החתימה, וכך מורים ל-Cloud Storage לצפות לתחביר ACL שמשתמש בתחביר ACL ל-XML של Amazon S3. צריך לוודא שלרשימות ה-ACL של Amazon S3 שבהן משתמשים יש מיפוי למודל ACL של Cloud Storage. לדוגמה, אם הכלים והספריות משתמשים בתחביר ACL של Amazon S3 כדי להעניק הרשאת WRITE לקטגוריה, הם צריכים גם להעניק את ההרשאה READ לקטגוריה, כי הרשאות ל-Cloud Storage הן קונצנטריות. כשמעניקים הרשאה ל-WRITE באמצעות התחביר של Cloud Storage, לא צריך לציין גם את ההרשאה WRITE וגם את ההרשאה READ.

Cloud Storage תומך בתחביר של רשימות ACL של Amazon S3 בתרחישים הבאים:

  • בעקבות בקשה ל-Cloud Storage לאחזר רשימות ACL (לדוגמה, אובייקט GET או בקשת קטגוריה של GET), Cloud Storage מחזיר את התחביר של Amazon S3.
  • בעקבות בקשה ל-Cloud Storage להחיל רשימות ACL (לדוגמה, אובייקט PUT או בקשת קטגוריה של PUT), Cloud Storage מצפה לקבל תחביר של רשימות ACL של Amazon S3.

בתרחיש העברה פשוטה, הכותרת Authorization משתמשת ב-AWS כמזהה החתימה, אבל עם מזהה הגישה שלכם ל-Cloud Storage HMAC.

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

בדוגמה הבאה מוצגת בקשה של GET ל-Cloud Storage להחזרת רשימות ACL של אובייקט.

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

התגובה לבקשה כוללת את ה-ACL תוך שימוש בתחביר ACL של 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>

בדוגמה הבאה מוצגת בקשה של PUT ל-Cloud Storage להגדרת רשימות ACL של אובייקט. בדוגמה מוצג גוף בקשה עם תחביר ACL של 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>

לסיום, בתרחיש העברה פשוטה, אפשר להשתמש גם במזהה החתימה GOOG1 בכותרת של Authorization. במקרה כזה, צריך להשתמש בתחביר של ה-ACL של Cloud Storage ולוודא שכל הכותרות x-amz-* משתנות ל-x-goog-*. אומנם זה אפשרי, אבל מומלץ לבחור העברה מלאה כדי ליהנות מכל היתרונות של Cloud Storage.

תמיכה בתאימות XML API עם Amazon S3

לדיונים על יכולת פעולה הדדית של XML API, עיינו במאמר Stack Overflow באמצעות התג google-cloud-storage.

המאמרים הבאים