Myl*_*lly 5 go google-cloud-storage google-cloud-kms go-cdk
我有一些代码可以从Google Cloud Storage上传和下载文件。下面是一个简短的示例:
import (
    "context"
    "io"
    "cloud.google.com/go/storage"
)
func upload(bucket, keyName, path string, reader io.Reader) error {
    ctx := context.Background()
    client, err := storage.NewClient(ctx)
    if err != nil {
        return err
    }
    defer client.Close()
    obj := client.Bucket(bucket).Object(path)
    writer := obj.NewWriter(ctx)
    defer writer.Close()
    writer.KMSKeyName = keyName
    if _, err = io.Copy(writer, reader); err != nil {
        return err
    }
    if err = writer.Close(); err != nil {
        return err
    }
    return nil
}
Run Code Online (Sandbox Code Playgroud)
棘手的部分是,我正在使用Google KMS来管理用于加密文件的密钥(Google的“客户管理的加密密钥”方案)。我的理解是这种加密发生在Google的一端。
我发现使用Go CDK的唯一解决方案是使用Google KMS加密文件,然后上传加密的Blob。没有办法像以前使用Go CDK一样指定加密密钥吗?
谢谢
如果您需要在 Go CDK 中使用特定于提供者的设置,则可以使用各种As函数来获取底层提供者 API 的句柄。在这种情况下,您需要使用该blob.WriterOptions.BeforeWrite选项。这样做的好处是,BeforeWrite如果您决定稍后切换存储桶提供程序(例如用于单元测试),则不会执行任何操作。
import (
    "context"
    "io"
    "cloud.google.com/go/storage"
    "gocloud.dev/blob"
    _ "gocloud.dev/blob/gcsblob" // link in "gs://" URLs
)
func upload(ctx context.Context, bucket, keyName, path string, reader io.Reader) error {
    bucket, err := blob.OpenBucket(ctx, "gs://" + bucket)
    if err != nil {
        return err
    }
    defer bucket.Close()
    writeCtx, cancelWrite := context.WithCancel(ctx)
    defer cancelWrite()
    writer, err := bucket.NewWriter(writeCtx, path, &blob.WriterOptions{
        // Use BeforeWrite to set provider-specific properties.
        BeforeWrite: func(asFunc func(interface{}) bool) error {
            var gcsWriter *storage.Writer
            // asFunc returns true if the writer can be converted to the type
            // pointed to.
            if asFunc(&gcsWriter) {
                gcsWriter.KMSKeyName = keyName
            }
            return nil
        },
    })
    if err != nil {
        return err
    }
    if _, err := io.Copy(writer, reader); err != nil {
        cancelWrite()  // Abort the write to the bucket.
        writer.Close()
        return err
    }
    if err := writer.Close(); err != nil {
        return err
    }
    return nil
}
Run Code Online (Sandbox Code Playgroud)
(虽然与您的问题没有直接关系,但我在代码中添加了中止写入错误以避免部分对象上传到您的存储提供商。我们正在添加文档,这些文档将演示如何在将来使用 Go CDK API 执行常见任务,参见#1576。)