Wie kann man mit boto3 auf Schlüssel aus Eimern mit Punkten (.) Im Namen zugreifen?

Kontex

Ich versuche, für alle meine Buckets einen Verschlüsselungsstatus für einen Sicherheitsbericht zu erhalten. Da die Verschlüsselung jedoch auf Schlüsselebene erfolgt, möchte ich alle Schlüssel durchlaufen und einen allgemeinen Verschlüsselungsstatus erhalten. Beispiel: "yes" ist, dass alle Schlüssel verschlüsselt sind, "no", wenn keiner verschlüsselt ist, und "partial" ist, dass einige verschlüsselt sind.
Ich muss boto3 verwenden, da es ein bekanntes Problem mit boto gibt, bei dem der Verschlüsselungsstatus für jeden Schlüssel immer None zurückgibt.Siehe hier

Proble

Ich versuche, mit boto3 alle Schlüssel in jedem meiner Eimer zu durchlaufen. Der folgende Code funktioniert einwandfrei, bis Buckets mit Namen ausgeführt werden, die Punkte enthalten, z. B. "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...

Wenn es einen Eimer mit einem Punkt im Namen trifft, wird diese Ausnahme ausgelöst, wennbucket.objects.all() wird aufgerufen und fordert mich auf, alle Anforderungen an einen bestimmten Endpunkt zu senden. Dieser Endpunkt befindet sich im ausgelösten Ausnahmeobjekt.

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.
Things habe ich versucht Setzen Sie den Parameter endpoint_url auf den in der Ausnahmeantwort angegebenen Bucket-Endpunkt wies3_resource = session.resource('s3', endpoint_url='my.test.bucket.s3.amazonaws.com') Angabe der Region, in der sich der Bucket befindet, wies3_resource = session.resource('s3', region_name='eu-west-1')

ch glaube, das Problem ist ähnlich wiediese Stapelüberlauf-Frage in boto, wodurch das Problem behoben wird, indem der Parameter calling_format im s3Connection-Konstruktor festgelegt wird. Leider kann ich boto nicht verwenden (siehe oben).

Aktualisiere

Hier ist, was für mich gearbeitet hat. Es ist nicht der eleganteste Ansatz, aber er funktioniert =).

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...

Antworten auf die Frage(4)

Ihre Antwort auf die Frage