Как копировать файлы между корзинами S3 в 2 разных аккаунтах с помощью boto3

Я пытаюсь загрузить файлы из корзины S3 поставщика в мою корзину S3, используя boto3. Я использую службу sts, чтобы взять на себя роль для доступа к корзине поставщика s3. Я могу подключиться к корзине поставщиков и получить список корзин. Я сталкиваюсь с ошибкой CopyObject operation: Access Denied при копировании в корзину. Вот мой сценарий

session = boto3.session.Session(profile_name = "s3_transfer")
sts_client = session.client("sts", verify=False)
assumed_role_object = sts_client.assume_role(
    RoleArn = "arn:aws:iam::<accountid>:role/assumedrole",
    RoleSessionName = "transfer_session",
    ExternalId = "<ID>",
    DurationSeconds=18000,
)

creds = assumed_role_object["Credentials"]
src_s3 = boto3.client(
    "s3",
    aws_access_key_id=creds["AccessKeyId"],
    aws_secret_access_key=creds["SecretAccessKey"],
    aws_session_token=creds["SessionToken"],
    verify=False,
)
paginator =src_s3.get_paginator("list_objects_v2")
# testing with just 2 items.
# TODO: Remove MaxItems once script works.
pages = paginator.paginate(
    Bucket = "ven_bucket", Prefix = "client", PaginationConfig = {"MaxItems": 2, "PageSize": 1000}
)
dest_s3 = session.client("s3", verify=False)
for page in pages:
    for obj in page["Contents"]:
        src_key = obj["Key"]
        des_key = dest_prefix + src_key[len(src_prefix) :]
        src = {"Bucket": "ven_bucket", "Key": src_key}
        print(src)
        print(des_key)
        dest_s3.copy(src, "my-bucket", des_key, SourceClient=src_s3)

Строка dest_s3.copy... - это место, где я получаю сообщение об ошибке. У меня есть следующая политика моего пользователя aws, позволяющая копировать в мое ведро

{
    "Version": "2012-10-17",
   "Statement": [
    {
        "Sid": "VisualEditor1",
        "Effect": "Allow",
        "Action": [
            "s3:*"
        ],
        "Resource": [
            "arn:aws:s3:::my-bucket/*",
            "arn:aws:s3:::my-bucket/"
        ]
    }
    ]
}

Я получаю следующую ошибку при запуске вышеуказанного скрипта.

botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the CopyObject operation: Access Denied

Учетные данные, которые вы используете для вызова операции копирования, должны иметь доступ к объекту в исходном сегменте и к объекту в сегменте назначения.

jarmod 30.05.2019 17:15

@jarmod Я могу получить доступ к объекту в исходном сегменте, используя эти учетные данные. И из политики учетной записи пользователя я также должен иметь возможность копировать в целевую учетную запись, если я что-то не упустил. Я могу загрузить файлы из источника на свой локальный компьютер, а затем загрузить их в место назначения, используя эти учетные данные. Тогда ошибка возникает при попытке скопировать напрямую из источника в пункт назначения.

Satish 30.05.2019 17:21

Если учетные данные, которые вы используете для копии, имеют доступ к исходным объектам, то почему вы используете временные учетные данные STS для перечисления исходных объектов (используя src_s3)?

jarmod 30.05.2019 18:35

Доступ @jarmod к корзине с исходным кодом осуществляется через предполагаемую роль sts.

Satish 30.05.2019 18:57

Если я неправильно прочитал ваш код, доступ к исходному сегменту для операции копирования не использует кредиты STS. Он использует кредиты s3_transfer. Операция копирования использует один набор кредитов (и только один), и это кредиты, связанные с клиентом dest_s3.

jarmod 30.05.2019 21:26

@jarmod Я использую кредиты sts, чтобы взять на себя роль, и запросить временные кредиты. Затем я использую эти временные кредиты для создания исходного клиента s3. Если это не так, можете ли вы показать, как я должен переписать это? Спасибо.

Satish 30.05.2019 21:32

Давайте продолжить обсуждение в чате.

jarmod 30.05.2019 22:27

принятый ответ сработал для вас? Можете ли вы опубликовать обновленный код, пожалуйста?

saadi 23.03.2020 19:23

@saadi У меня было 2 клиента s3, один из которых был подключен к учетной записи src, а другой — к целевой учетной записи. Затем я загружаю файл from из src с помощью клиента src, а затем загружаю его в цель с помощью целевого клиента.

Satish 24.03.2020 14:46
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
9
8 383
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Команду CopyObject() можно использовать для копирования объектов между сегментами без загрузки/выгрузки. По сути, два сегмента S3 взаимодействуют друг с другом и передают данные.

Эту команду также можно использовать для копирования между корзинами в разных регионах и разных учетных записях AWS.

Если вы хотите копировать между корзины, принадлежащие разным учетным записям AWS, вам нужно будет использовать единый набор учетных данных, который имеет:

  • GetObject разрешение на исходное ведро
  • PutObject разрешение на целевое ведро

Также обратите внимание, что команда CopyObject() — это отправлено на целевой счет. Сегмент назначения фактически извлекает объекты из исходной корзины.

Судя по вашему описанию, ваш код получение роли из другого аккаунта для получения разрешения на чтение в исходном сегменте. К сожалению, этого недостаточно для команды CopyObject(), потому что команда должна быть отправлена ​​в корзину назначения. (Да, это немного сложно понять из документации. Вот почему исходное ведро имеет конкретное имя, а не целевое ведро.)

Следовательно, в вашей ситуации, чтобы иметь возможность копировать объекты, вам потребуется использовать набор учетных данных из Account-B (пункт назначения), у которого также есть разрешение на чтение из Bucket-A (источника). Для этого поставщику потребуется изменить политику корзины, связанный с Bucket-A.

Если они не хотят этого делать, то ваш единственный вариант — загрузить объекты, используя предполагаемую роль, а затем отдельно загрузить файлы в свою корзину, используя учетные данные из вашей собственной Account-B.

Другие вопросы по теме