【问题标题】:How to copy the object in s3 from account A to Account B with updated object ownership to object A如何将 s3 中的对象从帐户 A 复制到帐户 B,并将对象所有权更新到对象 A
【发布时间】:2020-07-16 22:35:20
【问题描述】:

我的代码将对象从账户 A 复制到账户 B

import json
import boto3
from datetime import datetime, timedelta

def lambda_handler(event, context):
    # TODO implement

    SOURCE_BUCKET = 'Bucket-A'
    DESTINATION_BUCKET = 'Bucket-B'

    s3_client = boto3.client('s3')

    # Create a reusable Paginator
    paginator = s3_client.get_paginator('list_objects_v2')

    # Create a PageIterator from the Paginator
    page_iterator = paginator.paginate(Bucket=SOURCE_BUCKET)

    # Loop through each object, looking for ones older than a given time period
    for page in page_iterator:
        if "Contents" in page:
            for object in page['Contents']:
                if object['LastModified'] < datetime.now().astimezone() - timedelta(minutes=5):   # <-- Change time period here
                    print(f"Moving {object['Key']}")

                    # Copy object
                    s3_client.copy_object(
                        ACL='bucket-owner-full-control',
                        Bucket=DESTINATION_BUCKET,
                        Key=object['Key'],
                        CopySource={'Bucket':SOURCE_BUCKET, 'Key':object['Key']}
                    )

                    # Delete original object
                    s3_client.delete_object(Bucket=SOURCE_BUCKET, Key=object['Key'])
        else:
            print("No Contents key for page!")

lambda 函数角色策略是:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject*",
                "s3:List*",
                "s3:GetObject*",
                "s3:GetBucketLocation",
                "s3:DeleteObject*"
            ],
            "Resource": [
                "arn:aws:s3:::Bucket-A/*",
                "arn:aws:s3:::bucket-A"
            ]
        },
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "s3:PutObjectAcl",
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::bucket-B/*"
        }
    ]
}


aws s3api get-object-acl --bucket bucket-b --key key1
{
    "Owner": {
        "DisplayName": "accountA",
        "ID": "MYIDA"
    },
    "Grants": [
        {
            "Grantee": {
                "DisplayName": "accountA",
                "ID": "MyIDA",
                "Type": "CanonicalUser"
            },
            "Permission": "FULL_CONTROL"
        },
        {
            "Grantee": {
                "DisplayName": "accountb",
                "ID": "MyIDB",
                "Type": "CanonicalUser"
            },
            "Permission": "FULL_CONTROL"
        }
    ]
} 

从账户 A 复制到账户 B 到账户 B 时如何更改对象的所有者

 {
        "Owner": {
            "DisplayName": "accountB",
            "ID": "MYIDB"
        },

【问题讨论】:

  • 您的代码在执行复制时正确设置了 ACL。因此,该对象归拥有存储桶的 AWS 账户所有,而不是特定用户。
  • 不,该对象归转移对象的帐户所有,即帐户 A,我希望它到帐户 b
  • 如果来自 Account-A 的凭证用于将对象复制到 Account-B 拥有的存储桶中,则指定 ACL='bucket-owner-full-control' 将把控制权交给 Account-B。如果来自 Account-B 的凭据用于将对象从 Account-A 复制到 Account-B,则 Account-B 将拥有它(不需要 ACL)。
  • 如果您看到 get acl 命令,它将所有者作为帐户 A,并且我正在使用附加到 lambda 的角色。我应该用帐户 B 凭据替换它吗?
  • 最好使用来自目标帐户的凭据,这样可以避免 ACL 问题。请注意,这意味着需要修改源存储桶上的存储桶策略,以允许 GetObject 访问用于复制的 IAM 角色或 IAM 用户。

标签: amazon-web-services amazon-s3


【解决方案1】:

我将尝试先解决您的问题,然后为用例提供更好的方法。

首先,正如您正确识别的那样,您正在寻找的是对象 ACL。 Boto3 为您提供了一种 方法来检索和更新对象 ACL,从而为对象所有者提供 方法来检索对象 ACL,从而检索对象所有者以及更新 ACL。在官方文档here 中阅读更多相关信息。要了解对象 ACL,您可以参考文档here

作为参考,这里有一个示例请求语法:

response = object_acl.put(
    ACL='private'|'public-read'|'public-read-write'|'authenticated-read'|'aws-exec-read'|'bucket-owner-read'|'bucket-owner-full-control',
    AccessControlPolicy={
        'Grants': [
            {
                'Grantee': {
                    'DisplayName': 'string',
                    'EmailAddress': 'string',
                    'ID': 'string',
                    'Type': 'CanonicalUser'|'AmazonCustomerByEmail'|'Group',
                    'URI': 'string'
                },
                'Permission': 'FULL_CONTROL'|'WRITE'|'WRITE_ACP'|'READ'|'READ_ACP'
            },
        ],
        'Owner': {
            'DisplayName': 'string',
            'ID': 'string'
        }
    },
    GrantFullControl='string',
    GrantRead='string',
    GrantReadACP='string',
    GrantWrite='string',
    GrantWriteACP='string',
    RequestPayer='requester',
    VersionId='string'
)

现在找到一种更好的方法来实现这一点。看看 AWS 跨区域复制。在公告帖子here 中阅读更多相关信息或参考docs

要使用文档中的描述:

复制支持跨 Amazon S3 存储桶自动异步复制对象。为对象复制配置的存储桶可以由同一个 AWS 账户拥有,也可以由不同的账户拥有。您可以在不同 AWS 区域或同一区域内复制对象。

维护不同所有权下的对象副本 — 无论谁拥有源对象,您都可以告诉 Amazon S3 将副本所有权更改为拥有目标存储桶的 AWS 账户。这称为所有者覆盖选项。您可以使用此选项来限制对对象副本的访问。

基本上,您可以使用 LifeCycle Policies 并使整个过程自动化。您还可以使用新所有者配置要创建的目标对象。这样,您就可以将管理工作转移到 AWS 上,并使流程具有响应性。从长远来看,这将帮助您节省人力成本和资源使用方面的成本。

【讨论】:

  • 跨区域复制不足以满足我的情况。如果你看到我的代码,你会发现我想要移动超过一个小时的对象。所以复制后我应该更改对象 ACL?
  • 复制对象时不能这样做吗?
  • ACL 是一个对象属性,您需要对象能够设置它的 ACL。您对此有什么特别的担忧吗?还是代码质量问题?
  • 只是代码质量,你能告诉我代码是什么样子的吗,sn-p?
  • "...检索和更新对象 ACL,从而更新对象所有者。" 不,对象 ACL 不传达所有权。
猜你喜欢
  • 2017-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多