Любой способ использовать предварительно загруженные URL-адреса и применять теги?

Есть ли способ выдать заранее назначенный URL-адрес клиенту, чтобы загрузить файл на S3, и убедиться, что загруженный файл имеет определенные теги? Используя Python SDK здесь в качестве примера, он генерирует URL по желанию:

s3.generate_presigned_url('put_object', 
                          ExpiresIn=3600,
                          Params=dict(Bucket='foo', 
                                      Key='bar', 
                                      ContentType='text/plain', 
                                      Tagging='foo=bar'))

Это удовлетворительно при загрузке с явным указанием тегов:

$ curl 'https://foo.s3.amazonaws.com/bar?AWSAccessKeyId=...&Signature=...&content-type=text%2Fplain&x-amz-tagging=foo%3Dbar&Expires=1538404508' \
  -X PUT
  -H 'Content-Type: text/plain' \
  -H 'x-amz-tagging: foo=bar' \
  --data-binary foobar

Однако S3 также принимает запрос при пропуске -H 'x-amz-tagging: foo=bar', который загружает объект без тегов. Поскольку я не могу контролировать клиента, это... плохо.

Я попытался сначала создать пустой объект и пометить его, а затем выдать предварительно назначенный URL-адрес, но PUTЭтот объект полностью заменяет его, включая удаление любых тегов.

Я пытался выдать назначенный POST URL, но это, кажется, не поддерживает tagging параметр вообще:

s3.generate_presigned_post('foo', 'bar', {'tagging': '<Tagging><TagSet><Tag><Key>Foo</Key><Value>Bar</Value></Tag></TagSet></Tagging>'})
$ curl https://foo.s3.amazonaws.com/ \
  -F key=bar \
  -F 'tagging=<Tagging><TagSet><Tag><Key>Foo</Key><Value>Bar</Value></Tag></TagSet></Tagging>'
  -F AWSAccessKeyId=... \
  -F policy=... \
  -F signature=... \
  -F file=@/tmp/foo

<Error><Code>AccessDenied</Code><Message>Invalid according to Policy:
Extra input fields: tagging</Message>...

Я просто хочу позволить клиенту загрузить файл непосредственно в S3 и убедиться, что он помечен определенным образом в процессе. Есть ли способ сделать это?

3 ответа

Решение

Попробуйте следующий код:

fields = {
    "x-amz-meta-u1": "value1",
    "x-amz-meta-u2": "value2"
}
conditions = [
    {"x-amz-meta-u1": "value1"},
    {"x-amz-meta-u2": "value2"}
]


presignedurl = s3_client.generate_presigned_post(
    bucket_name, "YOUR_BUCKET_NAME",
    Fields=copy.deepcopy(fields),
    Conditions=copy.deepcopy(conditions)
)

Код Python:

      fields = {
    'tagging': '<Tagging><TagSet><Tag><Key>Foo</Key><Value>Bar</Value></Tag></TagSet></Tagging>',
}
conditions = [
    {'tagging': '<Tagging><TagSet><Tag><Key>Foo</Key><Value>Bar</Value></Tag></TagSet></Tagging>'}
]


presigned_url = s3_client.generate_presigned_post(
    Bucket="foo",
    Key="file/key.json",
    Fields=copy.deepcopy(fields),
    Conditions=copy.deepcopy(conditions)
)

СВЕРНУТЬ команду:

      $ curl -v --form-string "tagging=<Tagging><TagSet><Tag><Key>Foo</Key><Value>Bar</Value></Tag></TagSet></Tagging>" \
    -F key=file/key.json \
    -F x-amz-algorithm=... \
    -F x-amz-credential=... \
    -F x-amz-date=... \
    -F x-amz-security-token=... \
    -F policy=...\
    -F x-amz-signature=... \
    -F file=@key.json \
    https://foo.s3.amazonaws.com/

Объяснение

Крайне важно, чтобы --form-stringиспользуется в команде CURL, иначе CURL будет интерпретировать =<как чтение в файл!

Также убедитесь, что key.jsonнаходится в вашем текущем рабочем каталоге, чтобы CURL загрузил файл на S3, используя предварительно подписанный URL-адрес.

Довольно интересный вопрос.

Да, в предварительно подписанном URL-адресе есть необязательный параметр "x-amz-tagging", так что это не обязательно.

Однако для обеспечения того, что ресурсы должны быть помечены, это должно быть достигнуто с использованием соответствующей политики IAM. т.е. ваше решение только с политикой IAM.

Я мог бы найти один пример для вашего понимания, который гарантирует, что экземпляр EC2 должен быть помечен как https://aws.amazon.com/premiumsupport/knowledge-center/iam-policy-tags-restrict/

(Следовательно, вам нужно настроить политику IAM в зависимости от необходимости)

Примечание. Существует также служба с именем AWS config, однако она предназначена только для целей мониторинга (соответствия), теперь она исправит вашу проблему, чтобы убедиться, что теги являются обязательными.

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