¿Cómo acceder a las claves de los cubos con puntos (.) En sus nombres usando boto3?

Contexto

Estoy tratando de obtener un estado de cifrado para todos mis depósitos para un informe de seguridad. Sin embargo, dado que el cifrado se basa en un nivel de clave, quiero iterar a través de todas las claves y obtener un estado de cifrado general. Por ejemplo, "sí" es que todas las claves están encriptadas, "no" si ninguna está encriptada y "parcialmente" si algunas están encriptadas.
Debo usar boto3 porque hay un problema conocido con boto en el que el estado de cifrado de cada clave siempre devuelve Ninguno.Mira aquí.

Problema

Estoy tratando de iterar sobre todas las claves en cada uno de mis cubos usando boto3. El siguiente código funciona bien hasta que se encuentra en cubos con nombres que contienen puntos, como "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...

Cuando golpea un cubo con un punto en el nombre, lanza esta excepción cuandobucket.objects.all() se llama y me dice que envíe todas las solicitudes a un punto final específico. Este punto final se puede encontrar en el objeto de excepción que se genera.

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.
Cosas que he intentadoEstablecer el parámetro endpoint_url en el punto final del depósito especificado en la respuesta de excepción comos3_resource = session.resource('s3', endpoint_url='my.test.bucket.s3.amazonaws.com')Especificando la región en la que se encuentra el depósito comos3_resource = session.resource('s3', region_name='eu-west-1')

Creo que el problema es similar aesta pregunta de stackoverflow en boto, que soluciona el problema estableciendo el parámetro calling_format en el constructor s3Connection. Desafortunadamente, no puedo usar boto (ver arriba).

Actualizar

Esto es lo que terminó funcionando para mí. No es el enfoque más elegante, pero funciona =).

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

Respuestas a la pregunta(2)

Su respuesta a la pregunta