5

環境

セキュリティ レポート用にすべてのバケットの暗号化ステータスを取得しようとしています。ただし、暗号化はキー レベル ベースであるため、すべてのキーを反復処理して、一般的な暗号化ステータスを取得したいと考えています。たとえば、「はい」はすべてのキーが暗号化されている場合、「いいえ」は暗号化されていない場合、「部分的に」は一部が暗号化されている場合です。
boto には、各キーの暗号化ステータスが常に None を返すという既知の問題があるため、boto3 を使用する必要があります。こちらをご覧ください。

問題

boto3 を使用して、各バケット内のすべてのキーを反復処理しようとしています。次のコードは、「my.test.bucket」などのピリオドを含む名前のバケットに到達するまで正常に機能します。

from boto3.session import Session

session = Session(aws_access_key_id=<ACCESS_KEY>,
                  aws_secret_access_key=<SECRET_KEY>,
                  aws_session_token=<TOKEN>)
s3_resource = session.resource('s3')

for bucket in s3_resource.buckets.all():
    for obj in bucket.objects.all():
        key = s3_resource.Object(bucket.name, obj.key)
        # Do some stuff with the key...

名前にピリオドが含まれるバケットにヒットすると、bucket.objects.all()が呼び出されたときにこの例外がスローされ、すべてのリクエストを特定のエンドポイントに送信するように指示されます。このエンドポイントは、スローされる例外オブジェクトで見つけることができます。

for obj in bucket.objects.all():
File "/usr/local/lib/python2.7/site-packages/boto3/resources/collection.py", line 82, in __iter__
for page in self.pages():
File "/usr/local/lib/python2.7/site-packages/boto3/resources/collection.py", line 165, in pages
for page in pages:
File "/usr/lib/python2.7/dist-packages/botocore/paginate.py", line 85, in __iter__
response = self._make_request(current_kwargs)
File "/usr/lib/python2.7/dist-packages/botocore/paginate.py", line 157, in _make_request
return self._method(**current_kwargs)
File "/usr/lib/python2.7/dist-packages/botocore/client.py", line 310, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/usr/lib/python2.7/dist-packages/botocore/client.py", line 395, in _make_api_call
raise ClientError(parsed_response, operation_name)botocore.exceptions.ClientError: An error occurred (PermanentRedirect) when calling the ListObjects operation: The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint.

私が試したこと

  • endpoint_url パラメーターを、例外応答で指定されたバケット エンドポイントに設定します。s3_resource = session.resource('s3', endpoint_url='my.test.bucket.s3.amazonaws.com')
  • バケットが配置されているリージョンを指定するs3_resource = session.resource('s3', region_name='eu-west-1')

この問題は、s3Connection コンストラクターで calling_format パラメーターを設定することで問題を解決する boto のこのスタックオーバーフローの質問に似ていると思います。残念ながら、boto は使えません (上記参照)。

アップデート

これが私のために働いたものです。これは最もエレガントなアプローチではありませんが、機能します =)。

from boto3.session import Session

session = Session(aws_access_key_id=<ACCESS_KEY>,
                  aws_secret_access_key=<SECRET_KEY>,
                  aws_session_token=<TOKEN>)
s3_resource = session.resource('s3')

# First get all the bucket names
bucket_names = [bucket.name for bucket in s3_resource.buckets.all()]


for bucket_name in bucket_names:
    # Check each name for a "." and use a different resource if needed
    if "." in bucket_name:
        region = session.client('s3').get_bucket_location(Bucket=bucket_name)['LocationConstraint']
        resource = session.resource('s3', region_name=region)
    else:
        resource = s3_resource
    bucket = resource.Bucket(bucket_name)

    # Continue as usual using this resource
    for obj in bucket.objects.all():
        key = resource.Object(bucket.name, obj.key)
        # Do some stuff with the key...
4

2 に答える 2

6

Benから提供された素晴らしい回答を一般化するだけです。

import boto3
knownBucket = 'some.topLevel.BucketPath.withPeriods'
s3 = boto3.resource('s3')

#get region
region = s3.meta.client.get_bucket_location(Bucket=knownBucket)['LocationConstraint']

#set region in resource
s3 = boto3.resource('s3',region_name=region)
于 2015-12-15T22:58:50.673 に答える